File Coverage

blib/lib/HTTP/ProxyCheck.pm
Criterion Covered Total %
statement 19 240 7.9
branch 0 124 0.0
condition 0 12 0.0
subroutine 6 28 21.4
pod 14 14 100.0
total 39 418 9.3


line stmt bran cond sub pod time code
1             #===============================================================================
2             # HTTP::ProxyCheck Version 1.4, Thu May 25 10:47:42 CEST 2006
3             #===============================================================================
4             # Copyright (c) 2004 - 2006 Thomas Weibel. All rights reserved.
5             #
6             # This library is free software; you can redistribute it and/or modify it
7             # under the same terms as Perl itself.
8             #
9             # More information: See "pod2text ProxyCheck.pm"
10             #===============================================================================
11              
12             package HTTP::ProxyCheck;
13              
14 1     1   19983 use strict;
  1         2  
  1         38  
15 1     1   5 use vars qw($answer $error $VERSION);
  1         1  
  1         57  
16 1     1   4 use warnings;
  1         5  
  1         22  
17              
18 1     1   2142 use Validate::Net;
  1         2124  
  1         27  
19 1     1   756 use IO::Socket;
  1         44114  
  1         3  
20              
21             BEGIN {
22 1     1   567 $VERSION = 1.4;
23 1         3 $answer = '';
24 1         2 $error = '';
25              
26             # Autoflush = True
27 1         2620 $| = 1;
28             }
29              
30             =head1 NAME
31              
32             HTTP::ProxyCheck - a class to check the functionality of HTTP proxy servers.
33              
34             =head1 SYNOPSIS
35              
36             use HTTP::ProxyCheck;
37            
38             my $proxy = 'proxy:8080';
39             my $url = 'http://search.cpan.org/';
40             my $proxy_check = new HTTP::ProxyCheck(
41             proxy => $proxy,
42             url => $url,
43             answer_size => 'header',
44             print_error => 0,
45             )
46             or die $HTTP::ProxyCheck::error;
47            
48             print "Trying to connect to '$proxy' and retrieve '$url'\n";
49            
50             if ( $proxy_check->check() ) {
51             print "'$proxy' returns:\n\n", $proxy_check->get_answer(), "\n\n";
52             }
53             else {
54             print "Error: ", $proxy_check->get_error(), "\n";
55             }
56              
57             =head1 DESCRIPTION
58              
59             HTTP::ProxyCheck is a class to check HTTP proxy servers. It connects to given
60             HTTP proxy servers and tries to retrieve a provided URL through them.
61              
62             =head1 CONSTRUCTOR
63              
64             =head2 new( [attribute => $value, ...] )
65              
66             C is the HTTP::ProxyCheck object constructor.
67              
68             If an error happens while constructing the object, use
69             C<$HTTP::ProxyCheck::error> to get the error message.
70              
71             All named attributes of C are optional.
72              
73             B
74              
75             =over 10
76              
77             =item * proxy => $proxy
78              
79             Specifies the address of the proxy server to check. This can also be done with
80             C.
81              
82             The proxy server address has to match the patter 'host:port'. Host and port are
83             tested whether they are valid. If you want to disable this test, you can set
84             C<< check_proxy => 0 >>.
85              
86             =item * check_proxy => 1|0
87              
88             Set C<< check_proxy => 0 >> to disable the check whether the proxy server
89             address is valid.
90              
91             The default value of C is C<1> which means, the proxy server
92             address gets tested.
93              
94             This attribute can also be set with C.
95              
96             =item * url => $url
97              
98             Specifies the URL to use for the proxy server check. This can also be done
99             with C.
100              
101             The URL has to be of a valid form, e.g. 'http://search.cpan.org'. It gets
102             tested whether it is valid. If you want to disable this test, you can set
103             C<< check_url => 0 >>.
104              
105             =item * check_url => 1|0
106              
107             Set C<< check_url => 0 >> to disable the check whether the URL is valid.
108              
109             The default value of C is C<1> which means, the URL gets tested.
110              
111             This attribute can also be set with C.
112              
113             =item * answer_size => short|header|full
114              
115             Defines the size of the proxy server answer.
116              
117             C means that only the HTTP status code, e.g.
118              
119             HTTP/1.0 200 OK
120              
121             is returned.
122              
123             With C
the full HTTP header gets returned, e.g.
124              
125             HTTP/1.0 200 OK
126             Date: Tue, 12 Aug 2003 12:19:46 GMT
127             Server: Apache/1.3.27 (Unix) mod_perl/1.27
128             Cache-Control: max-age=3600
129             Expires: Tue, 12 Aug 2003 13:19:46 GMT
130             Last-Modified: Tue, 12 Aug 2003 12:19:46 GMT
131             Content-Type: text/html
132             X-Cache: MISS from search.cpan.org
133             X-Cache: MISS from hactar.earth.net
134             X-Cache-Lookup: HIT from hactar.earth.net:8080
135             Proxy-Connection: close
136              
137             Use C if you want the HTTP header including the whole data from the
138             proxy server.
139              
140             The default value of C is C
.
141              
142             This attribute can also be set with C.
143              
144             =item * user_agent => $user_agent
145              
146             Specifies the name of the user agent sent to the proxy.
147              
148             If you don't specify a user agent, "HTTP::ProxyCheck/1.4" is used.
149              
150             =item * verbose_errors => 0|1
151              
152             Set C<< verbose_errors => 1 >> to enable verbose error messages.
153              
154             Verbose error messages look like this:
155              
156             $method failed: $error_message
157              
158             And non-verbose error messages like this:
159              
160             $error_message
161              
162             The default value of C is C<0>.
163              
164             For more information see L.
165              
166             =item * print_error => 1|0
167              
168             Set C<< print_error => 0 >> to disable that error messages are displayed with
169             C.
170              
171             The default value of C is C<1>.
172              
173             For more information see L.
174              
175             =item * raise_error => 0|1
176              
177             Set C<< raise_error => 1 >> to enable that error messages are displayed with
178             C and the program is brought to an end.
179              
180             The default value of C is C<0>.
181              
182             For more information see L.
183              
184             =back
185              
186             B
187              
188             =over 10
189              
190             =item * Okay
191              
192             Blessed reference
193              
194             =item * Error
195              
196             C
197              
198             The error message can be retrieved with C<$HTTP::ProxyCheck::error>.
199              
200             =back
201              
202             =cut
203              
204             sub new {
205 0     0 1   my ( $class, %attr ) = @_;
206 0           my $self = bless( {%attr}, $class );
207              
208 0 0         if ( $self->_init ) {
209 0           return $self;
210             }
211             else {
212 0           return $self->_throw( $self->{error} );
213             }
214             }
215              
216             =head1 METHODS
217              
218             =head2 check( [attribute => $value, ...] )
219              
220             C does the actual proxy server checking. It connects to a specified
221             proxy server and tries to get a defined URL through it.
222              
223             All named attributes of C are optional, but C and C
224             must be either set as object or method attribute.
225              
226             B
227              
228             =over 10
229              
230             =item * proxy => $proxy
231              
232             Defines the proxy server to check.
233              
234             C<< proxy => $proxy >> has higher precedence than the object attribute
235             C. It is only used by this method call. It doesn't get saved as object
236             attribute or changes the object attribute. If you want to do this use
237             C.
238              
239             For more information see L.
240              
241             =item * check_proxy => 1|0
242              
243             Set C<< check_proxy => 0 >> to disable the check whether the proxy server
244             address is valid. If C<< check_proxy => 1 >> is set the proxy server
245             address gets tested.
246              
247             This method attribute has higher precedence than the object attribute
248             C. It is only used by this method call. It doesn't get saved as
249             object attribute or changes the object attribute. If you want to do this use
250             C.
251              
252             =item * url => $url
253              
254             Defines the URL to use with the proxy server check.
255              
256             C<< url => $url >> has higher precedence than the object attribute
257             C. It is only used by this method call. It doesn't get saved as object
258             attribute or changes the object attribute. If you want to do this use
259             C.
260              
261             For more information see L.
262              
263             =item * check_url => 1|0
264              
265             Set C<< check_url => 0 >> to disable the check whether the URL is valid. If
266             C<< check_url => 1 >> is set the URL gets tested.
267              
268             This method attribute has higher precedence than the object attribute
269             C. It is only used by this method call. It doesn't get saved as
270             object attribute or changes the object attribute. If you want to do this use
271             C.
272              
273             =item * answer_size => short|header|full
274              
275             Defines the size of the proxy server answer.
276              
277             This method attribute has higher precedence than the object attribute
278             C. It is only used by this method call. It doesn't get saved as
279             object attribute or changes the object attribute. If you want to do this use
280             C.
281              
282             For more information see L.
283              
284             =back
285              
286             B
287              
288             =over 10
289              
290             =item * Okay
291              
292             C<1>
293              
294             The answer of the proxy server can be retrieved with C or
295             C<$HTTP::ProxyCheck::answer>
296              
297             =item * Error
298              
299             C
300              
301             The error message can be retrieved with C or
302             C<$HTTP::ProxyCheck::error>
303              
304             =back
305              
306             =cut
307              
308             sub check {
309 0     0 1   my ( $self, %attr ) = @_;
310 0           my ( $check_proxy, $check_url, $proxy, $url, $answer_size, $user_agent );
311              
312             #---------------------------------------------------------------------------
313             # Parse attributes and set defaults
314             #---------------------------------------------------------------------------
315              
316             # Set the proxy check attribute
317 0 0         if ( defined $attr{check_proxy} ) {
318 0           $check_proxy = $self->_get_bool( $attr{check_proxy} );
319             }
320             else {
321 0           $check_proxy = $self->{check_proxy};
322             }
323              
324             # Set the URL check attribute
325 0 0         if ( defined $attr{check_url} ) {
326 0           $check_url = $self->_get_bool( $attr{check_url} );
327             }
328             else {
329 0           $check_url = $self->{check_url};
330             }
331              
332             # Set the proxy address
333 0 0         if ( defined $attr{proxy} ) {
    0          
334 0           $proxy = $attr{proxy};
335 0 0         unless ( $self->_check_proxy( $proxy, $check_proxy ) ) {
336 0           return $self->_throw( $self->{error} );
337             }
338             }
339             elsif ( defined $self->{proxy} ) {
340 0           $proxy = $self->{proxy};
341             }
342             else {
343 0           return $self->_throw(
344             q#No proxy defined. Set it as attribute of your 'HTTP::ProxyCheck' object or the 'check()' method. You can also set it with 'set_proxy()'.#
345             );
346             }
347              
348             # Set the URL
349 0 0         if ( defined $attr{url} ) {
    0          
350 0           $url = $attr{url};
351 0 0         unless ( $self->_check_url( $url, $check_url ) ) {
352 0           return $self->_throw( $self->{error} );
353             }
354             }
355             elsif ( defined $self->{url} ) {
356 0           $url = $self->{url};
357             }
358             else {
359 0           return $self->_throw(
360             q#No url defined. Set it as attribute of your 'HTTP::ProxyCheck' object or the 'check()' method. You can also set it with 'set_url()'.#
361             );
362             }
363              
364             # Set the answer size
365 0 0         if ( defined $attr{answer_size} ) {
    0          
366 0           $answer_size = $attr{answer_size};
367 0 0         unless ( $self->_check_answer_size($answer_size) ) {
368 0           return $self->_throw( $self->{error} );
369             }
370             }
371             elsif ( defined $self->{answer_size} ) {
372 0           $answer_size = $self->{answer_size};
373             }
374             else {
375 0           return $self->_throw(
376             q#No answer_size defined. Set it as attribute of your 'HTTP::ProxyCheck' object or the 'check()' method. You can also set it with 'set_answer_size()'.#
377             );
378             }
379              
380             # Set the user agent
381 0 0         if ( defined $attr{user_agent} ) {
    0          
382 0           $user_agent = $attr{user_agent};
383             }
384             elsif ( defined $self->{user_agent} ) {
385 0           $user_agent = $self->{user_agent};
386             }
387             else {
388 0           $user_agent = "HTTP::ProxyCheck/" . $VERSION;
389             }
390              
391             #---------------------------------------------------------------------------
392             # Proxy check
393             #---------------------------------------------------------------------------
394              
395 0           my ( $i, @answer, $answer, @header, $request, $line, $EOL );
396              
397 0           $EOL = "\015\012";
398              
399             # Fix to unset the error message of a previous IO::Socket::INET run
400             # Thanks to Ben Schnopp
401 0           undef $@;
402              
403             # Open socket to proxy server
404 0           my $socket = IO::Socket::INET->new(
405             PeerAddr => $proxy,
406             Proto => 'tcp',
407             Timeout => 5,
408             Type => SOCK_STREAM
409             );
410              
411             # If there was an error, throw an exception
412 0 0         if ($@) {
413 0           return $self->_throw("Couldn't connect to '$proxy'. $@");
414             }
415            
416             # Set request
417 0           $request = <<"REQUEST";
418             GET $url HTTP/1.0
419             Referer: None
420             User-Agent: $user_agent
421             Pragma: no-cache
422              
423             REQUEST
424              
425 0           $request =~ s/\n/\015\012/g;
426              
427             # Print request to the open socket
428 0           print $socket $request;
429            
430             # Read the answer of the proxy server to an array
431 0           while ( defined( $line = <$socket> ) ) {
432 0           $line =~ s/\n//g;
433 0           push @answer, $line;
434             }
435              
436 0           $answer = join "\n", @answer;
437              
438             # Throw an exception if the answer is empty
439 0 0 0       unless ( defined $answer && $answer !~ /^\s*$/ ) {
440 0           return $self->_throw("'$proxy' didn't return anything. Maybe '$proxy' is not the address of a proxy server.");
441             }
442            
443             # Parse the answer according to the requested answer size
444 0 0         if ( $answer_size eq 'short' ) {
    0          
445 0           $answer = $answer[0];
446             }
447             elsif ( $answer_size eq 'header' ) {
448 0           foreach (@answer) {
449 0 0 0       if ( !/^\s*
450 0           push @header, $_;
451             }
452             else {
453 0           last;
454             }
455             }
456 0           $answer = join "\n", @header;
457             }
458              
459             # Throw an exception if the parsed answer is empty
460 0 0 0       unless ( defined $answer && $answer !~ /^\s*$/ ) {
461 0           return $self->_throw(qq#'$proxy' didn't return a header. Try setting 'answer_size => "full"' as attribute of your 'HTTP::ProxyCheck' object or the 'check()' method. You can also use 'set_answer_size( "full" )'.#);
462             }
463              
464 0           close($socket);
465              
466 0           $self->_set_answer($answer);
467              
468 0           return 1;
469             }
470              
471             =head2 get_answer( )
472              
473             C gets the most recent proxy server answer.
474              
475             The proxy server answer is in the form specified by the C
476             attribute of the HTTP::ProxyCheck object or the C method.
477              
478             For more information see L.
479              
480             B
481              
482             =over 10
483              
484             =item * Okay
485              
486             C<< $proxy_check->{answer} >>
487              
488             This is the most recent proxy server answer.
489              
490             =item * Error
491              
492             C
493              
494             The error message can be retrieved with C or
495             C<$HTTP::ProxyCheck::error>
496              
497             =back
498              
499             =cut
500              
501             sub get_answer {
502 0     0 1   my ($self) = @_;
503              
504 0 0         unless ( defined $self->{answer} ) {
505 0           return $self->_throw('No answer returned so far.');
506             }
507              
508 0           return $self->{answer};
509             }
510              
511             =head2 get_error( )
512              
513             C gets the most recent error message.
514              
515             For more information see L.
516              
517             B
518              
519             =over 10
520              
521             =item * Okay
522              
523             C<< $proxy_check->{error} >>
524              
525             This is the most recent error message.
526              
527             =back
528              
529             =cut
530              
531             sub get_error {
532 0     0 1   my ($self) = @_;
533              
534 0 0         unless ( defined $self->{error} ) {
535 0           return $self->_throw('No error happened so far.');
536             }
537              
538 0           return $self->{error};
539             }
540              
541             =head2 get_proxy( )
542              
543             C gets the current value of the object attribute C.
544              
545             B
546              
547             =over 10
548              
549             =item * Okay
550              
551             C<< $proxy_check->{proxy} >>
552              
553             This is the current proxy server address.
554              
555             =item * Error
556              
557             C
558              
559             The error message can be retrieved with C or
560             C<$HTTP::ProxyCheck::error>
561              
562             =back
563              
564             =cut
565              
566             sub get_proxy {
567 0     0 1   my ($self) = @_;
568              
569 0 0         unless ( defined $self->{proxy} ) {
570 0           $self->_throw(
571             q#No proxy defined. Set it as attribute of your 'HTTP::ProxyCheck' object or with 'set_proxy()'.#
572             );
573             }
574              
575 0           return $self->{proxy};
576             }
577              
578             =head2 set_proxy( $proxy )
579              
580             C sets the value of the object attribute C.
581              
582             B
583              
584             =over 10
585              
586             =item * $proxy
587              
588             The proxy server address has to match the patter 'host:port'. Host and port are
589             tested whether they are valid. If you want to disable this test, you can set
590             the object attribute C<< check_proxy => 0 >> or use C.
591              
592             =back
593              
594             B
595              
596             =over 10
597              
598             =item * Okay
599              
600             C<1>
601              
602             =item * Error
603              
604             C
605              
606             The error message can be retrieved with C or
607             C<$HTTP::ProxyCheck::error>
608              
609             =back
610              
611             =cut
612              
613             sub set_proxy {
614 0     0 1   my ( $self, $proxy ) = @_;
615              
616 0 0         unless ( defined $proxy ) {
617 0           return $self->_throw('No proxy server defined.');
618             }
619              
620             # Check the proxy server address
621 0 0         unless ( $self->_check_proxy( $proxy, $self->{check_proxy} ) ) {
622 0           return $self->_throw( $self->{error} );
623             }
624              
625 0           $self->{proxy} = $proxy;
626              
627 0           return 1;
628             }
629              
630             =head2 get_check_proxy( )
631              
632             C gets the current value of the object attribute C.
633              
634             B
635              
636             =over 10
637              
638             =item * Okay
639              
640             C<< $proxy_check->{check_proxy} >>
641              
642             This is the current value of the C attribute.
643              
644             =back
645              
646             =cut
647              
648             sub get_check_proxy {
649 0     0 1   my ($self) = @_;
650              
651 0           return $self->{check_proxy};
652             }
653              
654             =head2 set_check_proxy( $check )
655              
656             C sets the object attribute C.
657              
658             B
659              
660             =over 10
661              
662             =item * $check
663              
664             Use C<0> to disable the check whether the proxy server address is valid and C<1>
665             to enable it.
666              
667             =back
668              
669             B
670              
671             =over 10
672              
673             =item * Okay
674              
675             C<1>
676              
677             =item * Error
678              
679             C
680              
681             The error message can be retrieved with C or
682             C<$HTTP::ProxyCheck::error>
683              
684             =back
685              
686             =cut
687              
688             sub set_check_proxy {
689 0     0 1   my ( $self, $check_proxy ) = @_;
690              
691 0 0         unless ( defined $check_proxy ) {
692 0           return $self->_throw(q#No 'check_proxy' value defined.#);
693             }
694              
695             # Get boolean value for $check_proxy
696 0           $check_proxy = $self->_get_bool( $check_proxy );
697            
698 0           $self->{check_proxy} = $check_proxy;
699              
700 0           return 1;
701             }
702              
703             =head2 get_url( )
704              
705             C gets the current value of the object attribute C.
706              
707             B
708              
709             =over 10
710              
711             =item * Okay
712              
713             C<< $proxy_check->{url} >>
714              
715             This is the current URL.
716              
717             =item * Error
718              
719             C
720              
721             The error message can be retrieved with C or
722             C<$HTTP::ProxyCheck::error>
723              
724             =back
725              
726             =cut
727              
728             sub get_url {
729 0     0 1   my ($self) = @_;
730              
731 0 0         unless ( defined $self->{url} ) {
732 0           $self->_throw(
733             q#No url defined. Set it as attribute of your 'HTTP::ProxyCheck' object or with 'set_url()'.#
734             );
735             }
736              
737 0           return $self->{url};
738             }
739              
740             =head2 set_url( $url )
741              
742             C sets the object attribute C.
743              
744             B
745              
746             =over 10
747              
748             =item * $url
749              
750             The URL has to be of a valid form, e.g. 'http://search.cpan.org'. It gets
751             tested whether it is valid. If you want to disable this test, you can set
752             the object attribute C<< check_url => 0 >> or use C.
753              
754             =back
755              
756             B
757              
758             =over 10
759              
760             =item * Okay
761              
762             C<1>
763              
764             =item * Error
765              
766             C
767              
768             The error message can be retrieved with C or
769             C<$HTTP::ProxyCheck::error>
770              
771             =back
772              
773             =cut
774              
775             sub set_url {
776 0     0 1   my ( $self, $url ) = @_;
777              
778 0 0         unless ( defined $url ) {
779 0           return $self->_throw('No URL defined.');
780             }
781              
782             # Check the URL
783 0 0         unless ( $self->_check_url( $url, $self->{check_url} ) ) {
784 0           return $self->_throw( $self->{error} );
785             }
786              
787 0           $self->{url} = $url;
788              
789 0           return 1;
790             }
791              
792             =head2 get_check_url( )
793              
794             C gets the current value of the object attribute C.
795              
796             B
797              
798             =over 10
799              
800             =item * Okay
801              
802             C<< $proxy_check->{check_url} >>
803              
804             This is the current value of the C attribute.
805              
806             =back
807              
808             =cut
809              
810             sub get_check_url {
811 0     0 1   my ($self) = @_;
812              
813 0           return $self->{check_url};
814             }
815              
816             =head2 set_check_url( $check )
817              
818             C sets the object attribute C.
819              
820             B
821              
822             =over 10
823              
824             =item * $check
825              
826             Use C<0> to disable the check whether the URL is valid and C<1> to enable it.
827              
828             =back
829              
830             B
831              
832             =over 10
833              
834             =item * Okay
835              
836             C<1>
837              
838             =item * Error
839              
840             C
841              
842             The error message can be retrieved with C or
843             C<$HTTP::ProxyCheck::error>
844              
845             =back
846              
847             =cut
848              
849             sub set_check_url {
850 0     0 1   my ( $self, $check_url ) = @_;
851              
852 0 0         unless ( defined $check_url ) {
853 0           return $self->_throw(q#No 'check_url' value defined.#);
854             }
855              
856             # Get boolean value for $check_url
857 0           $check_url = $self->_get_bool( $check_url );
858            
859 0           $self->{check_url} = $check_url;
860              
861 0           return 1;
862             }
863              
864             =head2 get_answer_size( )
865              
866             C gets the current value of the object attribute C.
867              
868             B
869              
870             =over 10
871              
872             =item * Okay
873              
874             C<< $proxy_check->{answer_size} >>
875              
876             This is the current answer size.
877              
878             =item * Error
879              
880             C
881              
882             The error message can be retrieved with C or
883             C<$HTTP::ProxyCheck::error>
884              
885             =back
886              
887             =cut
888              
889             sub get_answer_size {
890 0     0 1   my ($self) = @_;
891              
892 0 0         unless ( defined $self->{answer_size} ) {
893 0           $self->_throw(
894             q#No answer size defined. Set it as attribute of your 'HTTP::ProxyCheck' object or with 'set_answer_size()'.#
895             );
896             }
897              
898 0           return $self->{answer_size};
899             }
900              
901             =head2 set_answer_size( $answer_size )
902              
903             C sets the object attribute C.
904              
905             B
906              
907             =over 10
908              
909             =item * $answer_size
910              
911             Defines the size of the proxy server answer. Use either C, C
or
912             C as value.
913              
914             For more information see L.
915              
916             =back
917              
918             B
919              
920             =over 10
921              
922             =item * Okay
923              
924             C<1>
925              
926             =item * Error
927              
928             C
929              
930             The error message can be retrieved with C or
931             C<$HTTP::ProxyCheck::error>
932              
933             =back
934              
935             =cut
936              
937             sub set_answer_size {
938 0     0 1   my ( $self, $answer_size ) = @_;
939              
940 0 0         unless ( defined $answer_size ) {
941 0           return $self->_throw('No answer size defined.');
942             }
943              
944             # Check the answer size
945 0 0         unless ( $self->_check_answer_size($answer_size) ) {
946 0           return $self->_throw( $self->{error} );
947             }
948              
949 0           $self->{answer_size} = $answer_size;
950              
951 0           return 1;
952             }
953              
954             #-------------------------------------------------------------------------------
955             # Private method: _check_proxy()
956             #-------------------------------------------------------------------------------
957             # Checks whether a provided proxy server address complies with the pattern
958             # 'host:port'.
959             #
960             # Attributes
961             # * $proxy
962             # Defines the proxy server address to check.
963             # * $check_proxy
964             # Indicates whether to check the proxy server address or not. Possible
965             # values are
966             # '1' or '0'.
967             #
968             # Return values
969             # * Okay
970             # 1
971             # * Error
972             # undef
973             #-------------------------------------------------------------------------------
974              
975             sub _check_proxy {
976 0     0     my ( $self, $proxy, $check_proxy ) = @_;
977              
978 0 0         unless ( defined $proxy ) {
979 0           return undef;
980             }
981              
982 0 0         if ($check_proxy) {
983              
984             # Check proxy server address format
985 0 0         unless ( $proxy =~ /^(\S*):(\d{1,5})$/ ) {
986 0           $self->{error} =
987             "The specified proxy server '$proxy' doesn't comply with the pattern 'host:port' e.g. 'proxy:8080'.";
988 0           return undef;
989             }
990              
991 0           my $proxyhost = $1;
992 0           my $proxyport = $2;
993              
994             # Check proxy server host and port
995 0 0 0       unless ( Validate::Net->host($proxyhost)
996             && Validate::Net->port($proxyport) )
997             {
998 0           $self->{error} =
999             "The specified proxy server address '$proxy' is invalid. "
1000             . Validate::Net->reason() . ".";
1001 0           return undef;
1002             }
1003             }
1004              
1005 0           return 1;
1006             }
1007              
1008             #-------------------------------------------------------------------------------
1009             # Private method: _check_url()
1010             #-------------------------------------------------------------------------------
1011             # Checks whether a provided URL is a valid URL for HTTP::ProxyCheck e.g.
1012             # 'http://search.cpan.org'.
1013             #
1014             # Attributes
1015             # * $url
1016             # Defines the URL to check.
1017             # * $check_url
1018             # Indicates whether to check the URL or not. Possible values are '1' or '0'.
1019             #
1020             # Return values
1021             # * Okay
1022             # 1
1023             # * Error
1024             # undef
1025             #-------------------------------------------------------------------------------
1026              
1027             sub _check_url {
1028 0     0     my ( $self, $url, $check_url ) = @_;
1029              
1030 0 0         unless ( defined $url ) {
1031 0           return undef;
1032             }
1033              
1034 0 0         if ($check_url) {
1035              
1036             # Check URL format
1037 0 0         unless ( $url =~ m#^http://([^:/]+)(?::(\d+))?(?:/.*)?# ) {
1038 0           $self->{error} =
1039             "The specified URL '$url' doesn't comply with the pattern of a valid URL for HTTP::ProxyCheck e.g. 'http://search.cpan.org'";
1040 0           return undef;
1041             }
1042 0           my $host = $1;
1043 0           my $port = $2;
1044              
1045 0           my $invalid_url = "The specified URL '$url' is not valid. ";
1046              
1047             # Check host and port
1048 0 0         unless ( Validate::Net->host($host) ) {
1049 0           $self->{error} = $invalid_url . Validate::Net->reason() . ".";
1050 0           return undef;
1051             }
1052              
1053 0 0         if ( defined $port ) {
1054 0 0         unless ( Validate::Net->port($port) ) {
1055 0           $self->{error} = $invalid_url . Validate::Net->reason() . ".";
1056 0           return undef;
1057             }
1058             }
1059             }
1060              
1061 0           return 1;
1062             }
1063              
1064             #-------------------------------------------------------------------------------
1065             # Private method: _check_answer_size()
1066             #-------------------------------------------------------------------------------
1067             # Checks whethera provided answer size is valid.
1068             #
1069             # Attributes
1070             # * $answer_size
1071             # Specifies the answer size. Possible values are 'short', 'header' or
1072             # 'full'.
1073             #
1074             # Return values
1075             # * Okay
1076             # 1
1077             # * Error
1078             # undef
1079             #-------------------------------------------------------------------------------
1080              
1081             sub _check_answer_size {
1082 0     0     my ( $self, $answer_size ) = @_;
1083              
1084 0 0         unless ( defined $answer_size ) {
1085 0           return undef;
1086             }
1087              
1088             # The answer size must be either 'short', 'header' or 'full'
1089 0 0         unless ( $answer_size =~ m/^short|header|full$/ ) {
1090 0           $self->{error} =
1091             "The specified answer size '$answer_size' is invalid, use either 'header' or 'full'.";
1092 0           return undef;
1093             }
1094              
1095 0           return 1;
1096             }
1097              
1098             #-------------------------------------------------------------------------------
1099             # Private method: _throw()
1100             #-------------------------------------------------------------------------------
1101             # Throws an exeption with a message and optional with a specified return code.
1102             # If no return code is specified, 'undef' is returned.
1103             #
1104             # Attributes
1105             # * $message
1106             # Defines the error message.
1107             # * $return_code
1108             # Specifies an optional return code for scalar context (default is 'undef').
1109             # In list context, '()' (empty list) is used.
1110             #
1111             # Return values
1112             # * Okay
1113             # * Array context
1114             # () (empty list)
1115             # * Scalar context
1116             # $return_code
1117             #-------------------------------------------------------------------------------
1118              
1119             sub _throw {
1120 0     0     my ( $self, $message, $return_code ) = @_;
1121              
1122 0 0         unless ( defined $return_code ) {
1123 0           $return_code = undef;
1124             }
1125              
1126             # Get the method name
1127 0           my $method = ( caller 1 )[3];
1128              
1129             # If the verbose errors attribut is set, add 'method_name failed:' to the
1130             # error message
1131 0 0         if ( $self->{verbose_errors} ) {
1132 0           $message = "$method failed: " . $message;
1133             }
1134              
1135 0           $self->_set_error($message);
1136              
1137             # Throw the exception
1138 0 0         Carp::croak $self->{error} if $self->{raise_error};
1139 0 0         Carp::carp $self->{error} if $self->{print_error};
1140              
1141             # Return the return code in the right context
1142 0 0         if (wantarray) {
1143 0           return ();
1144             }
1145             else {
1146 0           return $return_code;
1147             }
1148             }
1149              
1150             #-------------------------------------------------------------------------------
1151             # Private method: _set_error()
1152             #-------------------------------------------------------------------------------
1153             # Sets $self->{error} and $error and returns the previous error message.
1154             #
1155             # Attributes
1156             # * $my_error
1157             # Defines the error message.
1158             #
1159             # Return values
1160             # * Okay
1161             # $prev_error
1162             # * Error
1163             # undef
1164             #-------------------------------------------------------------------------------
1165              
1166             sub _set_error {
1167 0     0     my ( $self, $my_error ) = @_;
1168 0           my $prev_error = $self->{error};
1169              
1170 0 0         unless ( defined $my_error ) {
1171 0           return undef;
1172             }
1173              
1174 0           $self->{error} = $my_error;
1175 0           $error = $my_error;
1176              
1177 0           return $prev_error;
1178             }
1179              
1180             #-------------------------------------------------------------------------------
1181             # Private method: _set_answer()
1182             #-------------------------------------------------------------------------------
1183             # Sets $self->{answer} and $answer and returns the previous answer.
1184             #
1185             # Attributes
1186             # * $my_answer
1187             # Defines the proxy server answer.
1188             #
1189             # Return values
1190             # * Okay
1191             # $prev_answer
1192             # * Error
1193             # undef
1194             #-------------------------------------------------------------------------------
1195              
1196             sub _set_answer {
1197 0     0     my ( $self, $my_answer ) = @_;
1198 0           my $prev_answer = $self->{answer};
1199              
1200 0 0         unless ( defined $my_answer ) {
1201 0           return undef;
1202             }
1203              
1204 0           $self->{answer} = $my_answer;
1205 0           $answer = $my_answer;
1206              
1207 0           return $prev_answer;
1208             }
1209              
1210             #-------------------------------------------------------------------------------
1211             # Private method: _get_bool()
1212             #-------------------------------------------------------------------------------
1213             # Translates values to boolean value. '0' remains '0', 'undef' is translated to
1214             # the default value and every other value is gets '1'.
1215             #
1216             # Attributes
1217             # * $value
1218             # Specifies the value to translate.
1219             # * $default
1220             # Defines the default value for undefined values.
1221             #
1222             # Return values
1223             # * True
1224             # 1
1225             # * False
1226             # 0
1227             #-------------------------------------------------------------------------------
1228              
1229             sub _get_bool {
1230 0     0     my ( $self, $value, $default ) = @_;
1231              
1232             # Check and set $default
1233 0 0         if ( defined $default ) {
1234 0 0         unless ( $default eq 0 ) {
1235 0           $default = 1;
1236             }
1237             }
1238             else {
1239 0           $default = 1;
1240             }
1241              
1242             # Check and set $value
1243 0 0         if ( defined $value ) {
1244 0 0         unless ( $value eq 0 ) {
1245 0           $value = 1;
1246             }
1247             }
1248             else {
1249 0           $value = $default;
1250             }
1251              
1252 0           return $value;
1253             }
1254              
1255             #-------------------------------------------------------------------------------
1256             # Private method: _init()
1257             #-------------------------------------------------------------------------------
1258             # Initializes the default values of the attributes of new().
1259             #
1260             # Return values
1261             # * Okay
1262             # 1
1263             # * Error
1264             # undef
1265             #-------------------------------------------------------------------------------
1266              
1267             sub _init {
1268 0     0     my ($self) = @_;
1269 0           my $verbose_errors = $self->{verbose_errors};
1270 0           my $print_error = $self->{print_error};
1271 0           my $raise_error = $self->{raise_error};
1272 0           my $check_proxy = $self->{check_proxy};
1273 0           my $check_url = $self->{check_url};
1274 0           my $proxy = $self->{proxy};
1275 0           my $url = $self->{url};
1276 0           my $answer_size = $self->{answer_size};
1277              
1278             # Set the verbose errors attribute
1279 0           $self->{verbose_errors} = $self->_get_bool( $verbose_errors, 0 );
1280              
1281             # Set the print error attribute
1282 0           $self->{print_error} = $self->_get_bool( $print_error, 1 );
1283              
1284             # Set the raise error attribute
1285 0           $self->{raise_error} = $self->_get_bool( $raise_error, 0 );
1286              
1287             # Set the check proxy attribute
1288 0           $self->{check_proxy} = $self->_get_bool( $check_proxy, 1 );
1289              
1290             # Set the check URL attribute
1291 0           $self->{check_url} = $self->_get_bool( $check_url, 1 );
1292              
1293             # Check the proxy server address
1294 0 0         if ( defined $proxy ) {
1295 0 0         unless ( $self->_check_proxy( $proxy, $self->{check_proxy} ) ) {
1296 0           return undef;
1297             }
1298 0           $self->{proxy} = $proxy;
1299             }
1300              
1301             # Check the URL
1302 0 0         if ( defined $url ) {
1303 0 0         unless ( $self->_check_url( $url, $self->{check_url} ) ) {
1304 0           return undef;
1305             }
1306 0           $self->{url} = $url;
1307             }
1308              
1309             # Check the answer size
1310 0 0         if ( defined $answer_size ) {
1311 0 0         unless ( $self->_check_answer_size($answer_size) ) {
1312 0           return undef;
1313             }
1314             }
1315             else {
1316 0           $answer_size = 'header';
1317             }
1318 0           $self->{answer_size} = $answer_size;
1319              
1320 0           return 1;
1321             }
1322              
1323             1;
1324              
1325             __END__