File Coverage

blib/lib/LWP/Curl.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package LWP::Curl;
2              
3 5     5   300049 use warnings;
  5         15  
  5         185  
4 5     5   28 use strict;
  5         10  
  5         139  
5 5     5   2548 use Net::Curl::Easy qw(:constants);
  0            
  0            
6             use Carp qw(croak);
7             use Data::Dumper;
8             use URI::Escape;
9              
10             =head1 NAME
11              
12             LWP::Curl - LWP methods implementation with Curl engine
13              
14             =head1 VERSION
15              
16             Version 0.14
17              
18             =cut
19              
20             our $VERSION = '0.14';
21              
22             =head1 SYNOPSIS
23              
24             use LWP::Curl;
25            
26             my $lwpcurl = LWP::Curl->new();
27             my $content = $lwpcurl->get('http://search.cpan.org','http://www.cpan.org');
28             # get the page http://search.cpan.org passing with referer http://www.cpan.org
29              
30             =head1 DESCRIPTION
31              
32             LWP::Curl provides an interface similar to the LWP library, but is built on top of the Curl library.
33             The simple LWP-style interface means you don't have to know anything about the underlying library.
34              
35             =head1 Constructor
36              
37             =head2 new()
38              
39             Creates and returns a new LWP::Curl object, hereafter referred to as
40             the "lwpcurl".
41              
42             my $lwpcurl = LWP::Curl->new()
43              
44             =over 4
45              
46             =item * C<< timeout => sec >>
47              
48             Set the timeout value in seconds. The default timeout value is
49             180 seconds, i.e. 3 minutes.
50              
51             =item * C<< headers => [0|1] >>
52              
53             Show HTTP headers when return a content. The default is false '0'
54              
55             =item * C<< user_agent => 'agent86' >>
56              
57             Set the user agent string. The default is 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)'
58              
59             =item * C<< followlocation => [0|1] >>
60              
61             If true, the user-agent will honor HTTP 301 (redirect) status messages. The default is 1.
62              
63             =item * C<< auto_encode => [0|1] >>
64              
65             If true, urls will be urlencoded for GET and POST requests. Default is 1.
66              
67             =item * C<< maxredirs => number >>
68              
69             Set how many redirect requests will be honored by the user-agent. The default is 3.
70              
71             =item * C<< proxy => $proxyurl >>
72              
73             Set the proxy in the constructor, $proxyurl will be like:
74             http://myproxy.com:3128/
75             http://username:password@proxy.com:3128/
76              
77             libcurl respects the environment variables http_proxy, ftp_proxy,
78             all_proxy etc, if any of those are set. The $lwpcurl->proxy option does
79             however override any possibly set environment variables.
80              
81             =back
82              
83             =cut
84              
85             sub new {
86              
87             # Check for common user mistake
88             croak("Options to LWP::Curl should be key/value pairs, not hash reference")
89             if ref( $_[1] ) eq 'HASH';
90              
91             my ( $class, %args ) = @_;
92              
93             my $self = {};
94              
95             my $log = delete $args{log};
96              
97             my $timeout = delete $args{timeout};
98             $timeout = 3 * 60 unless defined $timeout;
99              
100             my $headers = delete $args{headers};
101             $headers = 0 unless defined $headers;
102              
103             my $user_agent = delete $args{user_agent};
104             $user_agent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)'
105             unless defined $user_agent;
106              
107             my $maxredirs = delete $args{max_redirs};
108             $maxredirs = 3 unless defined $maxredirs;
109              
110             my $followlocation = delete $args{followlocation};
111             $followlocation = 1 unless defined $followlocation;
112              
113             $self->{auto_encode} = delete $args{auto_encode};
114             $self->{auto_encode} = 1 unless defined $self->{auto_encode};
115            
116             $self->{timeout} = $timeout;
117            
118             my $proxy = delete $args{proxy};
119             $self->{proxy} = undef unless defined $proxy;
120            
121             $self->{retcode} = undef;
122              
123             my $debug = delete $args{debug};
124             $self->{debug} = 0 unless defined $debug;
125             print STDERR "\n Hash Debug: \n" . Dumper($self) . "\n" if $debug;
126             $self->{agent} = Net::Curl::Easy->new();
127             $self->{agent}->setopt( CURLOPT_TIMEOUT, $timeout );
128             $self->{agent}->setopt( CURLOPT_USERAGENT, $user_agent );
129             $self->{agent}->setopt( CURLOPT_HEADER, $headers );
130             $self->{agent}->setopt( CURLOPT_AUTOREFERER, 1 ); # always true
131             $self->{agent}->setopt( CURLOPT_MAXREDIRS, $maxredirs );
132             $self->{agent}->setopt( CURLOPT_FOLLOWLOCATION, $followlocation );
133             $self->{agent}->setopt( CURLOPT_SSL_VERIFYPEER, 0 );
134             $self->{agent}->setopt( CURLOPT_VERBOSE, 0 ); #ubuntu bug
135             $self->{agent}->setopt( CURLOPT_PROXY, $proxy ) if $proxy;
136              
137             return bless $self, $class;
138             }
139              
140             =head1 METHODS
141              
142             =head2 $lwpcurl->get($url,$referer)
143              
144             Get content of $url, passing $referer if defined.
145              
146             use LWP::Curl;
147             my $referer = 'http://www.example.com';
148             my $get_url = 'http://www.example.com/foo';
149             my $lwpcurl = LWP::Curl->new();
150             my $content = $lwpcurl->get($get_url, $referer);
151              
152             The C method croak()'s if the request fails, so wrap an C around it if you want to
153             handle failure more elegantly.
154              
155             =cut
156              
157             sub get {
158             my ( $self, $url, $referer ) = @_;
159             my $agent = $self->{agent};
160              
161             if ( !$referer ) {
162             $referer = "";
163             }
164            
165             $url = uri_escape($url,"[^:./]") if $self->{auto_encode};
166             $agent->setopt( CURLOPT_REFERER, $referer );
167             $agent->setopt( CURLOPT_URL, $url );
168             $agent->setopt( CURLOPT_HTTPGET, 1 );
169              
170             my $content = "";
171             open( my $fileb, ">", \$content );
172             $agent->setopt( CURLOPT_WRITEDATA, $fileb );
173             $self->{retcode} = $agent->perform;
174              
175             if ( ! defined $self->{retcode} ) {
176             my $response_code = $agent->getinfo(CURLINFO_HTTP_CODE);
177             if ($response_code == 200 || ($response_code == 0 && $url =~ m!^file:!)) {
178             print("\nTransfer went ok\n") if $self->{debug};
179             return $content;
180             }
181             }
182              
183             croak( "An error happened: Host $url "
184             . $self->{agent}->strerror( $self->{retcode} )
185             . " ($self->{retcode})\n" );
186             return undef;
187             }
188              
189             =head2 $lwpcurl->post($url,$hash_form,$referer)
190            
191             POST the $hash_form fields in $url, passing $referer if defined:
192              
193             use LWP::Curl;
194            
195             my $lwpcurl = LWP::Curl->new();
196            
197             my $referer = 'http://www.examplesite.com/';
198             my $post_url = 'http://www.examplesite.com/post/';
199            
200             my $hash_form = {
201             'field1' => 'value1',
202             'field2' => 'value2',
203             }
204            
205             my $content = $lwpcurl->post($post_url, $hash_form, $referer);
206              
207             =cut
208              
209             sub post {
210             my ( $self, $url, $hash_form, $referer ) = @_;
211              
212             if ( !$referer ) {
213             $referer = "";
214             }
215              
216             if ( !$hash_form ) {
217             warn(qq{POST Data not defined});
218             }
219             else {
220              
221             #print STDERR Dumper $hash_form;
222             }
223              
224             $url = uri_escape($url,"[^:./]") if $self->{auto_encode};
225             my $post_string = join '&', map {; uri_escape($_) . '=' . uri_escape($hash_form->{$_}) } keys %{ $hash_form };
226              
227             $self->{agent}->setopt( CURLOPT_POSTFIELDS, $post_string );
228             $self->{agent}->setopt( CURLOPT_POST, 1 );
229             $self->{agent}->setopt( CURLOPT_HTTPGET, 0 );
230              
231             $self->{agent}->setopt( CURLOPT_REFERER, $referer );
232             $self->{agent}->setopt( CURLOPT_URL, $url );
233             my $content = "";
234             open( my $fileb, ">", \$content );
235             $self->{agent}->setopt( CURLOPT_WRITEDATA, $fileb );
236             $self->{retcode} = $self->{agent}->perform;
237              
238             if ( ! defined $self->{retcode} ) {
239             my $code;
240              
241             $code = $self->{agent}->getinfo(CURLINFO_HTTP_CODE);
242             if ($code =~ /^2/) {
243             return $content;
244             }
245             croak "$code request not successful\n";
246             } else {
247             croak( "An error happened: Host $url "
248             . $self->{agent}->strerror( $self->{retcode} )
249             . " ($self->{retcode})\n" );
250             }
251             }
252              
253             =head2 $lwpcurl->timeout($sec)
254              
255             Set the timeout to use for all subsequent requests, in seconds.
256             Defaults to 180 seconds.
257              
258             =cut
259              
260             sub timeout {
261             my ( $self, $timeout ) = @_;
262             if ( !$timeout ) {
263             return $self->{timeout};
264             }
265             $self->{timeout} = $timeout;
266             $self->{agent}->setopt( CURLOPT_TIMEOUT, $self->timeout );
267             }
268              
269             =head2 $lwpcurl->auto_encode($value)
270              
271             Turn on/off auto_encode.
272              
273             =cut
274              
275             sub auto_encode {
276             my ( $self, $value ) = @_;
277             if ( !$value ) {
278             return $self->{auto_encode};
279             }
280             $self->{auto_encode} = $value;
281             }
282              
283             =head2 $lwpcurl->agent_alias($alias)
284            
285             Sets the user agent string to the expanded version from a table
286             of actual user strings.
287             I<$alias> can be one of the following:
288              
289             =over 4
290              
291             =item * Windows IE 6
292              
293             =item * Windows Mozilla
294              
295             =item * Mac Safari
296              
297             =item * Mac Mozilla
298              
299             =item * Linux Mozilla
300              
301             =item * Linux Konqueror
302              
303             =back
304              
305             then it will be replaced with a more interesting one. For instance,
306              
307             $lwpcurl->agent_alias( 'Windows IE 6' );
308              
309             sets your User-Agent to
310              
311             Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
312              
313             =cut
314              
315             sub agent_alias {
316             my ( $self, $alias ) = @_;
317              
318             # CTRL+C from WWW::Mechanize, thanks for petdance
319             # ------------
320             my %known_agents = (
321             'Windows IE 6' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)',
322             'Windows Mozilla' =>
323             'Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4b) Gecko/20030516 Mozilla Firebird/0.6',
324             'Mac Safari' =>
325             'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/85 (KHTML, like Gecko) Safari/85',
326             'Mac Mozilla' =>
327             'Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.4a) Gecko/20030401',
328             'Linux Mozilla' =>
329             'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030624',
330             'Linux Konqueror' => 'Mozilla/5.0 (compatible; Konqueror/3; Linux)',
331             );
332              
333             if ( defined $known_agents{$alias} ) {
334             $self->{agent}->setopt( CURLOPT_USERAGENT, $known_agents{$alias} );
335             }
336             else {
337             warn(qq{Unknown agent alias "$alias"});
338             }
339             }
340              
341             =head2 $lwpcurl->proxy($proxyurl)
342              
343             Set the proxy in the constructor, $proxyurl will be like:
344             http://myproxy.com:3128/
345             http://username:password@proxy.com:3128/
346              
347             libcurl respects the environment variables http_proxy, ftp_proxy,
348             all_proxy etc, if any of those are set. The $lwpcurl->proxy option does
349             however override any possibly set environment variables.
350              
351             To disable proxy set $lwpcurl->proxy('');
352              
353             $lwpcurl->proxy without argument, return the current proxy
354              
355             =cut
356              
357             sub proxy {
358             my ( $self, $proxy ) = @_;
359             if ( !defined $proxy ) {
360             return $self->{proxy};
361             }
362             $self->{proxy} = $proxy;
363             $self->{agent}->setopt( CURLOPT_PROXY, $self->proxy );
364             }
365              
366             =head1 TODO
367              
368             This is a small list of features I'm plan to add. Feel free to contribute with your wishlist and comentaries!
369              
370             =over 4
371              
372             =item * Test for the upload method
373              
374             =item * Improve the Documentation and tests
375              
376             =item * Support Cookies
377              
378             =item * PASS in all tests of LWP
379              
380             =item * Make a patch to L, todo change engine, like "new(engine => 'LWP::Curl')"
381              
382             =back
383              
384             =head1 AUTHOR
385              
386             Lindolfo Rodrigues de Oliveira Neto, C<< >>
387              
388             =head1 BUGS
389              
390             Please report any bugs or feature requests to C, or through
391             the web interface at L. I will be notified, and then you'll
392             automatically be notified of progress on your bug as I make changes.
393              
394             =head1 SUPPORT
395              
396             You can find documentation for this module with the perldoc command.
397              
398             perldoc LWP::Curl
399              
400             You can also look for information at:
401              
402             =over 4
403              
404             =item * RT: CPAN's request tracker
405              
406             L
407              
408             =item * AnnoCPAN: Annotated CPAN documentation
409              
410             L
411              
412             =item * CPAN Ratings
413              
414             L
415              
416             =item * Search CPAN
417              
418             L
419              
420             =back
421              
422              
423             =head1 ACKNOWLEDGEMENTS
424              
425             Thanks to Breno G. Oliveira for the great tips.
426             Thanks for the LWP and WWW::Mechanize for the inspiration.
427             Thanks for Neil Bowers for the patches
428             Thanks for Mark Allen for the patches
429              
430             =head1 COPYRIGHT & LICENSE
431              
432             Copyright 2009 Lindolfo Rodrigues de Oliveira Neto, all rights reserved.
433              
434             This program is free software; you can redistribute it and/or modify it
435             under the same terms as Perl itself.
436              
437              
438             =cut
439              
440             1; # End of LWP::Curl