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 1     1   30602 use warnings;
  1         2  
  1         38  
4 1     1   7 use strict;
  1         2  
  1         94  
5 1     1   517 use WWW::Curl::Easy;
  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.11
17              
18             =cut
19              
20             our $VERSION = '0.12';
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 the spider receive a HTTP 301 ( Redirect ) they will follow?. The default is 1.
62              
63             =item * C<< auto_encode => [0|1] >>
64              
65             Turn on/off auto encode urls, for get/post.
66              
67             =item * C<< maxredirs => number >>
68              
69             Set how deep the spider will follow when receive HTTP 301 ( Redirect ). 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} = WWW::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 ( $self->{retcode} == 0 ) {
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             my $post_string = "";
225             foreach my $var ( keys %{$hash_form} ) {
226             $post_string = $post_string . "$var=$hash_form->{$var}";
227             $post_string = $post_string . "&";
228              
229             #print STDERR "var: $var - $hash_form->{$var}\n";
230             }
231              
232             $url = uri_escape($url,"[^:./]") if $self->{auto_encode};
233             $post_string = uri_escape($post_string,"[^:./]") if $self->{auto_encode};
234              
235             $self->{agent}->setopt( CURLOPT_POSTFIELDS, $post_string );
236             $self->{agent}->setopt( CURLOPT_POST, 1 );
237             $self->{agent}->setopt( CURLOPT_HTTPGET, 0 );
238              
239             $self->{agent}->setopt( CURLOPT_REFERER, $referer );
240             $self->{agent}->setopt( CURLOPT_URL, $url );
241             my $content = "";
242             open( my $fileb, ">", \$content );
243             $self->{agent}->setopt( CURLOPT_WRITEDATA, $fileb );
244             $self->{retcode} = $self->{agent}->perform;
245              
246             if ( $self->{retcode} == 0 ) {
247             my $code;
248              
249             $code = $self->{agent}->getinfo(CURLINFO_HTTP_CODE);
250             if ($code =~ /^2/) {
251             return $content;
252             }
253             croak "$code request not successful\n";
254             } else {
255             croak( "An error happened: Host $url "
256             . $self->{agent}->strerror( $self->{retcode} )
257             . " ($self->{retcode})\n" );
258             }
259             }
260              
261             =head2 $lwpcurl->timeout($sec)
262              
263             Set the timeout to use for all subsequent requests, in seconds.
264             Defaults to 180 seconds.
265              
266             =cut
267              
268             sub timeout {
269             my ( $self, $timeout ) = @_;
270             if ( !$timeout ) {
271             return $self->{timeout};
272             }
273             $self->{timeout} = $timeout;
274             $self->{agent}->setopt( CURLOPT_TIMEOUT, $self->timeout );
275             }
276              
277             =head2 $lwpcurl->auto_encode($value)
278              
279             Turn on/off auto_encode.
280              
281             =cut
282              
283             sub auto_encode {
284             my ( $self, $value ) = @_;
285             if ( !$value ) {
286             return $self->{auto_encode};
287             }
288             $self->{auto_encode} = $value;
289             }
290              
291             =head2 $lwpcurl->agent_alias($alias)
292            
293             Sets the user agent string to the expanded version from a table
294             of actual user strings.
295             I<$alias> can be one of the following:
296              
297             =over 4
298              
299             =item * Windows IE 6
300              
301             =item * Windows Mozilla
302              
303             =item * Mac Safari
304              
305             =item * Mac Mozilla
306              
307             =item * Linux Mozilla
308              
309             =item * Linux Konqueror
310              
311             =back
312              
313             then it will be replaced with a more interesting one. For instance,
314              
315             $lwpcurl->agent_alias( 'Windows IE 6' );
316              
317             sets your User-Agent to
318              
319             Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
320              
321             =cut
322              
323             sub agent_alias {
324             my ( $self, $alias ) = @_;
325              
326             # CTRL+C from WWW::Mechanize, thanks for petdance
327             # ------------
328             my %known_agents = (
329             'Windows IE 6' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)',
330             'Windows Mozilla' =>
331             'Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4b) Gecko/20030516 Mozilla Firebird/0.6',
332             'Mac Safari' =>
333             'Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en-us) AppleWebKit/85 (KHTML, like Gecko) Safari/85',
334             'Mac Mozilla' =>
335             'Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.4a) Gecko/20030401',
336             'Linux Mozilla' =>
337             'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030624',
338             'Linux Konqueror' => 'Mozilla/5.0 (compatible; Konqueror/3; Linux)',
339             );
340              
341             if ( defined $known_agents{$alias} ) {
342             $self->{agent}->setopt( CURLOPT_USERAGENT, $known_agents{$alias} );
343             }
344             else {
345             warn(qq{Unknown agent alias "$alias"});
346             }
347             }
348              
349             =head2 $lwpcurl->proxy($proxyurl)
350              
351             Set the proxy in the constructor, $proxyurl will be like:
352             http://myproxy.com:3128/
353             http://username:password@proxy.com:3128/
354              
355             libcurl respects the environment variables http_proxy, ftp_proxy,
356             all_proxy etc, if any of those are set. The $lwpcurl->proxy option does
357             however override any possibly set environment variables.
358              
359             To disable proxy set $lwpcurl->proxy('');
360              
361             $lwpcurl->proxy without argument, return the current proxy
362              
363             =cut
364              
365             sub proxy {
366             my ( $self, $proxy ) = @_;
367             if ( !defined $proxy ) {
368             return $self->{proxy};
369             }
370             $self->{proxy} = $proxy;
371             $self->{agent}->setopt( CURLOPT_PROXY, $self->proxy );
372             }
373              
374             =head1 TODO
375              
376             This is a small list of features I'm plan to add. Feel free to contribute with your wishlist and comentaries!
377              
378             =over 4
379              
380             =item * Test for the upload method
381              
382             =item * Improve the Documentation and tests
383              
384             =item * Support Cookies
385              
386             =item * PASS in all tests of LWP
387              
388             =item * Make a patch to L, todo change engine, like "new(engine => 'LWP::Curl')"
389              
390             =back
391              
392             =head1 AUTHOR
393              
394             Lindolfo Rodrigues de Oliveira Neto, C<< >>
395              
396             =head1 BUGS
397              
398             Please report any bugs or feature requests to C, or through
399             the web interface at L. I will be notified, and then you'll
400             automatically be notified of progress on your bug as I make changes.
401              
402             =head1 SUPPORT
403              
404             You can find documentation for this module with the perldoc command.
405              
406             perldoc LWP::Curl
407              
408             You can also look for information at:
409              
410             =over 4
411              
412             =item * RT: CPAN's request tracker
413              
414             L
415              
416             =item * AnnoCPAN: Annotated CPAN documentation
417              
418             L
419              
420             =item * CPAN Ratings
421              
422             L
423              
424             =item * Search CPAN
425              
426             L
427              
428             =back
429              
430              
431             =head1 ACKNOWLEDGEMENTS
432              
433             Thanks to Breno G. Oliveira for the great tips.
434             Thanks for the LWP and WWW::Mechanize for the inspiration.
435             Thanks for Neil Bowers for patches
436            
437             =head1 COPYRIGHT & LICENSE
438              
439             Copyright 2009 Lindolfo Rodrigues de Oliveira Neto, all rights reserved.
440              
441             This program is free software; you can redistribute it and/or modify it
442             under the same terms as Perl itself.
443              
444              
445             =cut
446              
447             1; # End of LWP::Curl