File Coverage

blib/lib/HTTP/Accept.pm
Criterion Covered Total %
statement 36 36 100.0
branch 17 20 85.0
condition 2 2 100.0
subroutine 3 3 100.0
pod 1 1 100.0
total 59 62 95.1


line stmt bran cond sub pod time code
1             package HTTP::Accept;
2              
3             # ABSTRACT: Parse the HTTP header 'Accept'
4              
5             our $VERSION = '0.02';
6              
7 1     1   68359 use Moo;
  1         11341  
  1         5  
8              
9             has string => ( is => 'ro', required => 1 );
10             has values => ( is => 'ro', lazy => 1, default => \&_parse_string );
11              
12             sub match {
13 48     48 1 26136 my ($self, @values_to_check) = @_;
14              
15 48 100       124 @values_to_check = grep{ defined $_ && length $_ } @values_to_check;
  62         269  
16 48 100       164 return '' if !@values_to_check;
17              
18 39 50       61 my @accepts = @{ $self->values || [] };
  39         1057  
19 39 100       621 return $values_to_check[0] if !@accepts;
20              
21 34         72 @values_to_check = map { lc $_ } @values_to_check;
  52         184  
22              
23             ACCEPT:
24 34         94 for my $accept ( @accepts ) {
25 42 100       123 return $values_to_check[0] if $accept eq '*/*';
26              
27 37         116 my ($cat, $type) = split /\//, $accept;
28              
29             VALUE:
30 37         69 for my $value ( @values_to_check ) {
31 50 100       162 return $value if $value eq $accept;
32              
33 37         88 my ($value_cat, $value_type) = split /\//, $value;
34              
35 37 100       103 next VALUE if $value_cat ne $cat;
36              
37 8 100       47 return $value if $type eq '*';
38             }
39             }
40              
41 11         50 return '';
42             }
43              
44             around BUILDARGS => sub {
45             my ($orig, $class, @args) = @_;
46            
47             return { string => $args[0] }
48             if @args == 1 && !ref $args[0];
49            
50             return $class->$orig(@args);
51             };
52              
53             sub _parse_string {
54 21     21   20381 my ($self) = @_;
55              
56 21         110 my @accepts = split /\s*,\s*/, $self->string;
57 21         44 my %weighted;
58              
59 21         48 for my $accept ( @accepts ) {
60 24         79 my ($accept_name, $quality) = split /;/, $accept;
61              
62 24   100     105 $quality //= 'q=1';
63 24 50       78 $quality = 'q=1' if $quality !~ m{q=};
64              
65 24         98 my ($weight) = $quality =~ m{q=([^;]*)};
66 24         41 push @{ $weighted{$weight} }, lc $accept_name;
  24         104  
67             }
68              
69 21 50       93 my @accept_names = map{ @{ $weighted{$_} || [] } } sort { $b <=> $a }keys %weighted;
  24         39  
  24         96  
  6         40  
70              
71 21         158 return \@accept_names;
72             }
73              
74             1;
75              
76             __END__