File Coverage

blib/lib/HON/Http/UrlChecker/Service.pm
Criterion Covered Total %
statement 69 69 100.0
branch 20 20 100.0
condition 6 6 100.0
subroutine 14 14 100.0
pod 6 6 100.0
total 115 115 100.0


line stmt bran cond sub pod time code
1             package HON::Http::UrlChecker::Service;
2              
3 5     5   79708 use 5.006;
  5         14  
4 5     5   16 use strict;
  5         5  
  5         79  
5 5     5   13 use warnings;
  5         11  
  5         90  
6              
7 5     5   1778 use URI;
  5         16712  
  5         105  
8 5     5   19 use Carp;
  5         5  
  5         256  
9 5     5   2239 use Readonly;
  5         13542  
  5         209  
10 5     5   2868 use LWP::UserAgent;
  5         115941  
  5         271  
11              
12             =head1 NAME
13              
14             HON::Http::UrlChecker::Service - HTTP Status Code Checker
15              
16             =head1 VERSION
17              
18             Version 0.02
19              
20             =cut
21              
22             our $VERSION = '0.02';
23              
24             =head1 SYNOPSIS
25              
26             use HON::Http::UrlChecker::Service;
27              
28             my @listOfStatus = checkUrl('http://www.example.com');
29              
30             =head1 DESCRIPTION
31              
32             Check status code, response headers, redirect location and redirect chain
33             of a HTTP connection.
34              
35             =cut
36              
37 5     5   33 use base 'Exporter';
  5         8  
  5         2400  
38             our @EXPORT_OK =
39             qw/p_createUserAgent p_getUrl p_parseResponse p_isUrlAllowed checkUrl/;
40              
41             Readonly::Scalar my $TIMEOUT => 1200;
42              
43             Readonly::Scalar my $MAXREDIRECT => 10;
44              
45             Readonly::Array my @HEADERFIELDS => qw(
46             location
47             server
48             content-type
49             title
50             date
51             );
52              
53             Readonly::Array my @RESPONSEFIELDS => qw(
54             protocol
55             code
56             message
57             );
58              
59             =head1 SUBROUTINES/METHODS
60              
61             =head2 checkUrl( $url )
62              
63             Check a url (status code, response headers, redirect location and
64             redirect chain).
65              
66             =cut
67              
68             sub checkUrl {
69 8     8 1 7612 my $url = shift;
70              
71 8 100       16 if ( p_isUrlAllowed($url) ) {
72 2         5 my $ua = p_createUserAgent();
73 2         4 my $response = p_getUrl( $ua, $url );
74 2         22134 my @listStatus = p_parseResponse($response);
75              
76 2         47 return @listStatus;
77             }
78             else {
79 6         199 croak "Wrong url: $url";
80             }
81             }
82              
83             =head1 PRIVATE SUBROUTINES/METHODS
84              
85             =head2 p_createUserAgent
86              
87             Return a LWP::UserAgent.
88             LWP::UserAgent objects can be used to dispatch web requests.
89              
90             =cut
91              
92             sub p_createUserAgent {
93 3     3 1 1784 my $ua = LWP::UserAgent->new;
94              
95 3         3909 $ua->timeout($TIMEOUT);
96 3         36 $ua->agent('HonBot');
97 3         110 $ua->env_proxy;
98 3         20193 $ua->max_redirect($MAXREDIRECT);
99              
100 3         23 return $ua;
101             }
102              
103             =head2 p_getUrl
104              
105             Dispatch a GET request on the given $url
106             The return value is a response object. See HTTP::Response for a description
107             of the interface it provides.
108              
109             =cut
110              
111             sub p_getUrl {
112 4     4 1 27677 my ( $ua, $url ) = @_;
113              
114 4         17 return $ua->get($url);
115             }
116              
117             =head2 p_retrieveInfo
118              
119             Retrieve desired fields from an HTTP::Response
120              
121             =cut
122              
123             sub p_retrieveInfo {
124 5     5 1 5 my $response = shift;
125              
126 5         7 my %locationStatus = ();
127 5         19 foreach my $field (@HEADERFIELDS) {
128 25 100       582 if ( defined $response->header($field) ) {
129 8         199 $locationStatus{$field} = $response->header($field);
130             }
131             }
132              
133 5         115 foreach my $field (@RESPONSEFIELDS) {
134 15 100       97 if ( defined $response->$field ) {
135 9         76 $locationStatus{$field} = $response->$field;
136              
137             # Put status code in integer
138 9 100       49 if ( $field eq 'code' ) {
139 5         9 $locationStatus{$field} = $locationStatus{$field} + 0;
140             }
141              
142 9 100       17 if ( $field eq 'message' ) {
143 9         24 $locationStatus{$field} = join q{ }, map { ucfirst lc } split q{ },
144 4         12 $locationStatus{$field};
145             }
146             }
147             }
148              
149 5         37 return %locationStatus;
150             }
151              
152             =head2 p_parseResponse
153              
154             Retrieve a list of Status from HTTP::Response
155              
156             =cut
157              
158             sub p_parseResponse {
159 4     4 1 1112 my $response = shift;
160              
161 4         6 my @listStatus = ();
162 4         10 my @redirects = $response->redirects;
163 4 100       52 if ( scalar @redirects > 0 ) {
164 1         3 foreach my $redirect (@redirects) {
165 1         2 my %status = p_retrieveInfo($redirect);
166 1         3 push @listStatus, \%status;
167             }
168             }
169 4         7 my %status = p_retrieveInfo($response);
170 4         7 push @listStatus, \%status;
171              
172 4         9 return @listStatus;
173             }
174              
175             =head2 p_isUrlAllowed
176              
177             Check if the url is formatted correctly
178              
179             =cut
180              
181             sub p_isUrlAllowed {
182 12     12 1 15 my $url = shift;
183              
184 12 100       26 return unless $url;
185 10         33 my $uri = URI->new($url);
186 10 100 100     15597 return unless $uri->scheme and $uri->opaque;
187              
188 5 100 100     375 if ( $uri->scheme eq 'http' or $uri->scheme eq 'https' ) {
189 2 100       33 return unless $uri->authority;
190             }
191              
192 4         109 return 1;
193             }
194              
195             =head1 AUTHOR
196              
197             William Belle, C<< >>
198              
199             =head1 BUGS AND LIMITATIONS
200              
201             Please report any bugs or feature requests to C, or through
202             the web interface at L. I will be notified, and then you'll
203             automatically be notified of progress on your bug as I make changes.
204              
205             =head1 SUPPORT
206              
207             You can find documentation for this module with the perldoc command.
208              
209             perldoc HON::Http::UrlChecker::Service
210              
211             You can also look for information at:
212              
213             =over 4
214              
215             =item * RT: CPAN's request tracker (report bugs here)
216              
217             L
218              
219             =item * AnnoCPAN: Annotated CPAN documentation
220              
221             L
222              
223             =item * CPAN Ratings
224              
225             L
226              
227             =item * Search CPAN
228              
229             L
230              
231             =back
232              
233             =head1 LICENSE AND COPYRIGHT
234              
235             Copyright 2016 William Belle.
236              
237             This program is distributed under the MIT (X11) License:
238             L
239              
240             Permission is hereby granted, free of charge, to any person
241             obtaining a copy of this software and associated documentation
242             files (the "Software"), to deal in the Software without
243             restriction, including without limitation the rights to use,
244             copy, modify, merge, publish, distribute, sublicense, and/or sell
245             copies of the Software, and to permit persons to whom the
246             Software is furnished to do so, subject to the following
247             conditions:
248              
249             The above copyright notice and this permission notice shall be
250             included in all copies or substantial portions of the Software.
251              
252             THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
253             EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
254             OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
255             NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
256             HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
257             WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
258             FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
259             OTHER DEALINGS IN THE SOFTWARE.
260              
261             =cut
262              
263             1; # End of HON::Http::UrlChecker::Service