File Coverage

blib/lib/Furl/Request.pm
Criterion Covered Total %
statement 58 60 96.6
branch 10 14 71.4
condition 2 4 50.0
subroutine 15 15 100.0
pod 6 9 66.6
total 91 102 89.2


line stmt bran cond sub pod time code
1             package Furl::Request;
2              
3 12     12   151914 use strict;
  12         23  
  12         457  
4 12     12   60 use warnings;
  12         27  
  12         654  
5 12     12   424 use utf8;
  12         332  
  12         198  
6 12     12   6892 use Class::Accessor::Lite;
  12         16577  
  12         99  
7 12     12   5967 use Furl::Headers;
  12         35  
  12         839  
8 12     12   668 use Furl::HTTP;
  12         24  
  12         14479  
9              
10             Class::Accessor::Lite->mk_accessors(qw/ method uri protocol headers content /);
11              
12             sub new {
13 6     6 0 243495 my $class = shift;
14 6         19 my ($method, $uri, $headers, $content) = @_;
15              
16 6 50       30 unless (defined $headers) {
17 0         0 $headers = +{};
18             }
19              
20 6 50       19 unless (defined $content) {
21 0         0 $content = '';
22             }
23              
24             bless +{
25 6         80 method => $method,
26             uri => $uri,
27             headers => Furl::Headers->new($headers),
28             content => $content,
29             }, $class;
30             }
31              
32             sub parse {
33 2     2 0 12103 my $class = shift;
34 2         6 my $raw_request = shift;
35              
36             # I didn't use HTTP::Parser::XS for following reasons:
37             # 1. parse_http_request() function omits request content, but need to deal it.
38             # 2. this function parses header to PSGI env, but env/header mapping is troublesome.
39              
40 2 50       48 return unless $raw_request =~ s!^(.+) (.+) (HTTP/1.\d+)\s*!!;
41 2         42 my ($method, $uri, $protocol) = ($1, $2, $3);
42              
43 2         69 my ($header_str, $content) = split /\015?\012\015?\012/, $raw_request, 2;
44              
45 2         8 my $headers = +{};
46 2         15 for (split /\015?\012/, $header_str) {
47 8         18 tr/\015\012//d;
48 8         39 my ($k, $v) = split /\s*:\s*/, $_, 2;
49 8         39 $headers->{lc $k} = $v;
50              
51             # complete host_port
52 8 100       25 if (lc $k eq 'host') {
53 2         9 $uri = $v . $uri;
54             }
55             }
56              
57 2 50       11 unless ($uri =~ /^http/) {
58 2         6 $uri = "http://$uri";
59             }
60              
61 2         11 my $req = $class->new($method, $uri, $headers, $content);
62 2         47 $req->protocol($protocol);
63 2         87 return $req;
64             }
65              
66             # alias
67             *body = \&content;
68              
69             # shorthand
70 2     2 1 6 sub content_length { shift->headers->content_length }
71 2     2 1 8 sub content_type { shift->headers->content_type }
72 1     1 1 1766 sub header { shift->headers->header(@_) }
73              
74             sub request_line {
75 2     2 1 2495 my $self = shift;
76              
77 2         8 my $path_query = $self->uri . ''; # for URI.pm
78 2         36 $path_query =~ s!^https?://[^/]+!!;
79              
80 2   50     9 my $method = $self->method || '';
81 2   50     15 my $protocol = $self->protocol || '';
82              
83 2         17 return "$method $path_query $protocol";
84             }
85              
86             sub as_http_request {
87 2     2 1 4 my $self = shift;
88              
89 2         14 require HTTP::Request;
90 2         10 my $req = HTTP::Request->new(
91             $self->method,
92             $self->uri,
93             [ $self->headers->flatten ],
94             $self->content,
95             );
96              
97 2         10154 $req->protocol($self->protocol);
98 2         59 return $req;
99             }
100              
101             sub as_hashref {
102 1     1 1 19 my $self = shift;
103              
104             return +{
105 1         5 method => $self->method,
106             uri => $self->uri,
107             protocol => $self->protocol,
108             headers => [ $self->headers->flatten ],
109             content => $self->content,
110             };
111             }
112              
113             sub as_string {
114 2     2 0 20 my $self = shift;
115              
116 2 100       5 join("\015\012",
    100          
117             $self->method . ' ' . $self->uri . (defined($self->protocol) ? ' ' . $self->protocol : ''),
118             $self->headers->as_string,
119             ref($self->content) =~ qr{\A(?:ARRAY|HASH)\z} ? Furl::HTTP->make_x_www_form_urlencoded($self->content) : $self->content,
120             );
121             }
122              
123             1;
124             __END__