File Coverage

lib/WWW/Curl/UserAgent/Request.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package WWW::Curl::UserAgent::Request;
2             {
3             $WWW::Curl::UserAgent::Request::VERSION = '0.9.6';
4             }
5              
6 1     1   5214 use Moose;
  0            
  0            
7             use WWW::Curl::Easy;
8              
9             has http_request => (
10             is => 'ro',
11             isa => 'HTTP::Request',
12             required => 1,
13             );
14              
15             has connect_timeout => (
16             is => 'ro',
17             isa => 'Int',
18             required => 1,
19             );
20              
21             has timeout => (
22             is => 'ro',
23             isa => 'Int',
24             required => 1,
25             );
26              
27             has keep_alive => (
28             is => 'ro',
29             isa => 'Bool',
30             required => 1,
31             );
32              
33             has followlocation => (
34             is => 'ro',
35             isa => 'Bool',
36             default => 0,
37             );
38              
39             has max_redirects => (
40             is => 'ro',
41             isa => 'Int',
42             default => -1,
43             );
44              
45             has curl_easy => (
46             is => 'ro',
47             isa => 'WWW::Curl::Easy',
48             lazy_build => 1,
49             );
50              
51             has header_ref => (
52             is => 'ro',
53             isa => 'Ref',
54             default => sub { my $header; \$header },
55             );
56              
57             has content_ref => (
58             is => 'ro',
59             isa => 'Ref',
60             default => sub { my $content; \$content },
61             );
62              
63             sub _build_curl_easy {
64             my $self = shift;
65              
66             my $easy = WWW::Curl::Easy->new;
67             my $request = $self->http_request;
68              
69             $easy->setopt( CURLOPT_CONNECTTIMEOUT_MS, $self->connect_timeout );
70             $easy->setopt( CURLOPT_HEADER, 0 );
71             $easy->setopt( CURLOPT_NOPROGRESS, 1 );
72             $easy->setopt( CURLOPT_TIMEOUT_MS, $self->timeout );
73             $easy->setopt( CURLOPT_URL, $request->uri );
74             $easy->setopt( CURLOPT_WRITEHEADER, $self->header_ref );
75             $easy->setopt( CURLOPT_WRITEDATA, $self->content_ref );
76             $easy->setopt( CURLOPT_FORBID_REUSE, !$self->keep_alive );
77             $easy->setopt( CURLOPT_FOLLOWLOCATION, $self->followlocation );
78             $easy->setopt( CURLOPT_MAXREDIRS, $self->max_redirects );
79              
80             # see https://github.com/pauldix/typhoeus/blob/master/lib/typhoeus/easy.rb#L197
81             if ( $request->method eq 'GET' ) {
82             $easy->setopt( CURLOPT_HTTPGET, 1 );
83             }
84             elsif ( $request->method eq 'POST' ) {
85             use bytes;
86             my $content = $request->content;
87             $easy->setopt( CURLOPT_POST, 1 );
88             $easy->setopt( CURLOPT_POSTFIELDSIZE, length $content );
89             $easy->setopt( CURLOPT_COPYPOSTFIELDS, $content );
90             }
91             elsif ( $request->method eq 'PUT' ) {
92             use bytes;
93             my $content = $request->content;
94             $easy->setopt( CURLOPT_UPLOAD, 1 );
95             $easy->setopt( CURLOPT_INFILE, \$content );
96             $easy->setopt( CURLOPT_INFILESIZE, length $content );
97             $easy->setopt( CURLOPT_READFUNCTION, \&_read_callback );
98             $easy->setopt( CURLOPT_WRITEFUNCTION, \&_chunk_callback );
99             }
100             elsif ( $request->method eq 'HEAD' ) {
101             $easy->setopt( CURLOPT_NOBODY, 1 );
102             }
103             else {
104             $easy->setopt( CURLOPT_CUSTOMREQUEST, uc $request->method );
105             }
106              
107             my @headers;
108             foreach my $h ( +$request->headers->header_field_names ) {
109             push( @headers, "$h: " . $request->header($h) );
110             }
111             push @headers, "Connection: close" unless $self->keep_alive;
112             $easy->setopt( CURLOPT_HTTPHEADER, \@headers )
113             if scalar(@headers);
114              
115             return $easy;
116             }
117              
118             sub _read_callback {
119             my ( $maxlength, $pointer ) = @_;
120             my $data = substr( $$pointer, 0, $maxlength );
121             $$pointer =
122             length($$pointer) > $maxlength
123             ? scalar substr( $$pointer, $maxlength )
124             : '';
125             return $data;
126             }
127              
128             sub _chunk_callback {
129             my ( $data, $pointer ) = @_;
130             ${$pointer} .= $data;
131             return length($data);
132             }
133              
134             no Moose;
135             __PACKAGE__->meta->make_immutable;
136             1;