| blib/lib/Slackware/Slackget/Network/Connection/HTTP.pm | |||
|---|---|---|---|
| Criterion | Covered | Total | % | 
| statement | 12 | 62 | 19.3 | 
| branch | 0 | 26 | 0.0 | 
| condition | 0 | 3 | 0.0 | 
| subroutine | 4 | 10 | 40.0 | 
| pod | 1 | 1 | 100.0 | 
| total | 17 | 102 | 16.6 | 
| line | stmt | bran | cond | sub | pod | time | code | 
|---|---|---|---|---|---|---|---|
| 1 | package Slackware::Slackget::Network::Connection::HTTP; | ||||||
| 2 | |||||||
| 3 | 1 | 1 | 1536 | use warnings; | |||
| 1 | 2 | ||||||
| 1 | 41 | ||||||
| 4 | 1 | 1 | 6 | use strict; | |||
| 1 | 3 | ||||||
| 1 | 36 | ||||||
| 5 | |||||||
| 6 | 1 | 1 | 1102 | use LWP::Simple ; | |||
| 1 | 164547 | ||||||
| 1 | 14 | ||||||
| 7 | 1 | 1 | 573 | use File::Basename ; | |||
| 1 | 2 | ||||||
| 1 | 1366 | ||||||
| 8 | require File::Copy; | ||||||
| 9 | require HTTP::Status ; | ||||||
| 10 | require Slackware::Slackget::Network::Connection ; | ||||||
| 11 | require Time::HiRes ; | ||||||
| 12 | require Slackware::Slackget::Status ; | ||||||
| 13 | # use POE::Component::Client::HTTP; | ||||||
| 14 | |||||||
| 15 | =head1 NAME | ||||||
| 16 | |||||||
| 17 | Slackware::Slackget::Network::Connection::HTTP - This class encapsulate LWP::Simple | ||||||
| 18 | |||||||
| 19 | =head1 VERSION | ||||||
| 20 | |||||||
| 21 | Version 1.0.0 | ||||||
| 22 | |||||||
| 23 | =cut | ||||||
| 24 | |||||||
| 25 | our $VERSION = '1.0.0'; | ||||||
| 26 | # our @ISA = qw( Slackware::Slackget::Network::Connection ) ; | ||||||
| 27 | |||||||
| 28 | =head1 SYNOPSIS | ||||||
| 29 | |||||||
| 30 | This class encapsulate LWP::Simple, and provide some methods for the treatment of HTTP requests. | ||||||
| 31 | |||||||
| 32 | You can't use this class without the Slackware::Slackget::Network::Connection one. | ||||||
| 33 | |||||||
| 34 | This class need the following extra CPAN modules : | ||||||
| 35 | |||||||
| 36 | - LWP::Simple | ||||||
| 37 | - Time::HiRes | ||||||
| 38 | |||||||
| 39 | use Slackware::Slackget::Network::Connection::HTTP; | ||||||
| 40 | |||||||
| 41 | my $foo = Slackware::Slackget::Network::Connection::HTTP->new(); | ||||||
| 42 | ... | ||||||
| 43 | |||||||
| 44 | This module require the following modules from CPAN : LWP::Simple, Time::HiRes. | ||||||
| 45 | |||||||
| 46 | =cut | ||||||
| 47 | |||||||
| 48 | sub new | ||||||
| 49 | { | ||||||
| 50 | 0 | 0 | 1 | my ($class,$url,$config) = @_ ; | |||
| 51 | 0 | my $self = {}; | |||||
| 52 | # return undef if(!defined($config) && ref($config) ne 'HASH'); | ||||||
| 53 | 0 | 0 | return undef unless (is_url($self,$url)); | ||||
| 54 | 0 | bless($self,$class); | |||||
| 55 | 0 | $self->parse_url($url) ; | |||||
| 56 | 0 | return $self; | |||||
| 57 | } | ||||||
| 58 | |||||||
| 59 | =head1 CONSTRUCTOR | ||||||
| 60 | |||||||
| 61 | =head2 new | ||||||
| 62 | |||||||
| 63 | This class is not designed to be instanciate alone or used alone. You have to use the Slackware::Slackget::Network::Connection. | ||||||
| 64 | |||||||
| 65 | =head1 FUNCTIONS | ||||||
| 66 | |||||||
| 67 | =head2 test_server | ||||||
| 68 | |||||||
| 69 | This method test the rapidity of the mirror, by timing a head request on the FILELIST.TXT file. | ||||||
| 70 | |||||||
| 71 | my $time = $self->test_server() ; | ||||||
| 72 | |||||||
| 73 | =cut | ||||||
| 74 | |||||||
| 75 | sub __test_server { | ||||||
| 76 | 0 | 0 | my $self = shift ; | ||||
| 77 | # print "[debug http] protocol : $self->{DATA}->{protocol}\n"; | ||||||
| 78 | # print "[debug http] host : $self->{DATA}->{host}\n"; | ||||||
| 79 | 0 | my $server = "$self->{DATA}->{protocol}://$self->{DATA}->{host}/"; | |||||
| 80 | 0 | 0 | $server .= $self->{DATA}->{path}.'/' if($self->{DATA}->{path}); | ||||
| 81 | 0 | $server .= 'FILELIST.TXT'; | |||||
| 82 | 0 | $server = $self->strip_slash($server); | |||||
| 83 | # print "[debug http] Testing a HTTP server: $server\n"; | ||||||
| 84 | 0 | my $start_time = Time::HiRes::time(); | |||||
| 85 | # print "[debug http] \$start_time : $start_time\n"; | ||||||
| 86 | 0 | 0 | my @head = head($server) or return undef; | ||||
| 87 | 0 | my $stop_time = Time::HiRes::time(); | |||||
| 88 | # print "[debug http] \$stop_time: $stop_time\n"; | ||||||
| 89 | 0 | return ($stop_time - $start_time); | |||||
| 90 | } | ||||||
| 91 | |||||||
| 92 | =head2 __get_file | ||||||
| 93 | |||||||
| 94 | Download and return a given file. | ||||||
| 95 | |||||||
| 96 | my $file = $connection->get_file('PACKAGES.TXT') ; | ||||||
| 97 | |||||||
| 98 | =cut | ||||||
| 99 | |||||||
| 100 | sub __get_file { | ||||||
| 101 | 0 | 0 | my ($self,$remote_file) = @_ ; | ||||
| 102 | 0 | 0 | $remote_file = $self->file unless(defined($remote_file)) ; | ||||
| 103 | 0 | return get($self->strip_slash($self->protocol().'://'.$self->host().'/'.$self->path().'/'.$remote_file)); | |||||
| 104 | } | ||||||
| 105 | |||||||
| 106 | =head2 __fetch_file | ||||||
| 107 | |||||||
| 108 | Download and store a given file. | ||||||
| 109 | |||||||
| 110 | $connection->fetch_file() ; # download the file $connection->file and store it at $config->{common}->{'update-directory'}/$connection->file, this way is not recommended | ||||||
| 111 | or | ||||||
| 112 | $connection->fetch_file($remote_file) ; # download the file $remote_file and store it at $config->{common}->{'update-directory'}/$connection->file, this way is not recommended | ||||||
| 113 | or | ||||||
| 114 | $connection->fetch_file('PACKAGES.TXT',"$config->{common}->{'update-directory'}/".$current_specialfilecontainer_object->id."/PACKAGES.TXT") ; # This is the recommended way. | ||||||
| 115 | # This is equivalent to : $connection->fetch_file($remote_file,$local_file) ; | ||||||
| 116 | |||||||
| 117 | This method return a Slackware::Slackget::Status object with the following object declaration : | ||||||
| 118 | |||||||
| 119 | my $state = Slackware::Slackget::Status->new(codes => { | ||||||
| 120 |  		0 => "All goes well. Server said: $ret_code - ".status_message( $ret_code ),  | 
||||||
| 121 |  		1 => "Server error, you must choose the next host for this server. Server said: $ret_code - $tmp_status_message",  | 
||||||
| 122 |  		2 => "Client error, it seems that you have a problem with you connection or with the slackget10 library  (or with a library which we depended on). It is also possible that the file we try to download was not on the remote server. Server said: $ret_code - $tmp_status_message",  | 
||||||
| 123 |  		3 => "Server has redirected us, we prefer direct connection, change host for this server. Server said: $ret_code - $tmp_status_message",  | 
||||||
| 124 |  		4 => "The HTTP connection is not a success and we are not able to know what, we recommend to change the current host of this server. Server said: $ret_code - $tmp_status_message"  | 
||||||
| 125 | }); | ||||||
| 126 | |||||||
| 127 | This is the direct code of this method :) | ||||||
| 128 | |||||||
| 129 | =cut | ||||||
| 130 | |||||||
| 131 | sub __fetch_file { | ||||||
| 132 | 0 | 0 | my ($self,$remote_file,$local_file) = @_ ; | ||||
| 133 | 0 | 0 | $remote_file = $self->file unless(defined($remote_file)); | ||||
| 134 | 0 | 0 | unless(defined($local_file)){ | ||||
| 135 | 0 | 0 | 0 | if(defined($self->{DATA}->{download_directory}) && -e $self->{DATA}->{download_directory}){ | |||
| 0 | |||||||
| 136 | 0 | $remote_file=~ /([^\/]*)$/; | |||||
| 137 | 0 | $local_file = $self->{DATA}->{download_directory}.'/'.$1 ; | |||||
| 138 | } | ||||||
| 139 | elsif(defined($self->{DATA}->{config})){ | ||||||
| 140 | 0 | $remote_file=~ /([^\/]*)$/; | |||||
| 141 | 0 | $local_file = $self->{DATA}->{config}->{common}->{'update-directory'}.'/'.$1 ; | |||||
| 142 | } | ||||||
| 143 | else{ | ||||||
| 144 | 0 | warn "[Slackware::Slackget::Network::Connection::HTTP] unable to determine the path to save $remote_file.\n"; | |||||
| 145 | 0 | return undef; | |||||
| 146 | } | ||||||
| 147 | } | ||||||
| 148 | 0 | my $url = $self->protocol().'://'.$self->host().'/'.$self->path().'/'.$remote_file; | |||||
| 149 | 0 | $url = $self->strip_slash($url); | |||||
| 150 | # print "\n[debug http] save the fetched file ($url) to $local_file\n"; | ||||||
| 151 | 0 | my $ret_code = getstore($url,$local_file.'.part') ; | |||||
| 152 | 0 | File::Copy::move($local_file.'.part',$local_file); | |||||
| 153 | 0 | my $tmp_status_message = status_message( $ret_code ); | |||||
| 154 | 0 |  	$tmp_status_message=~ s/\n/ /g;  | 
|||||
| 155 | 0 | my $state = Slackware::Slackget::Status->new(codes => { | |||||
| 156 |  		0 => "All goes well. Server said: $ret_code - $tmp_status_message",  | 
||||||
| 157 |  		1 => "Server error, you must choose the next host for this server. Server said: $ret_code - $tmp_status_message",  | 
||||||
| 158 |  		2 => "Client error, it seems that you have a problem with you connection or with the Slackware::Slackget library  (or with a library which we depended on). It is also possible that the file we try to download was not on the remote server. Server said: $ret_code - $tmp_status_message",  | 
||||||
| 159 |  		3 => "Server has redirected us, we prefer direct connection, change host for this server. Server said: $ret_code - $tmp_status_message",  | 
||||||
| 160 |  		4 => "The HTTP connection is not a success and we are not able to know what is the problem, we recommend to change the current host of this server. Server said: $ret_code - $tmp_status_message"  | 
||||||
| 161 | }); | ||||||
| 162 | 0 | 0 | if(is_success($ret_code)){ | ||||
| 163 | 0 | File::Copy::move( $local_file.'.part' , $local_file ); | |||||
| 164 | 0 | $state->current(0); | |||||
| 165 | } | ||||||
| 166 | else | ||||||
| 167 | { | ||||||
| 168 | 0 | 0 | if(HTTP::Status::is_server_error($ret_code)) | ||||
| 0 | |||||||
| 0 | |||||||
| 169 | { | ||||||
| 170 | |||||||
| 171 | 0 | $state->current(1); | |||||
| 172 | |||||||
| 173 | } | ||||||
| 174 | elsif(HTTP::Status::is_client_error($ret_code)) | ||||||
| 175 | { | ||||||
| 176 | 0 | $state->current(2); | |||||
| 177 | } | ||||||
| 178 | elsif(HTTP::Status::is_redirect($ret_code)) | ||||||
| 179 | { | ||||||
| 180 | 0 | $state->current(3); | |||||
| 181 | } | ||||||
| 182 | else | ||||||
| 183 | { | ||||||
| 184 | 0 | $state->current(4); | |||||
| 185 | } | ||||||
| 186 | } | ||||||
| 187 | 0 | return $state; | |||||
| 188 | } | ||||||
| 189 | |||||||
| 190 | =head2 __fetch_all | ||||||
| 191 | |||||||
| 192 | This method fetch all files declare in the "files" parameter of the constructor. | ||||||
| 193 | |||||||
| 194 | $connection->fetch_all or die "Unable to fetch all files\n"; | ||||||
| 195 | |||||||
| 196 | This method save all files in the $config->{common}->{'update-directory'} directory (so you have to manage yourself the files deletion/replacement problems) | ||||||
| 197 | |||||||
| 198 | =cut | ||||||
| 199 | |||||||
| 200 | sub __fetch_all { | ||||||
| 201 | 0 | 0 | my $self = shift ; | ||||
| 202 | 0 | foreach (@{$self->files}){ | |||||
| 0 | |||||||
| 203 | 0 | 0 | $self->fetch_file($_) or return undef; | ||||
| 204 | } | ||||||
| 205 | 0 | return 1 ; | |||||
| 206 | } | ||||||
| 207 | |||||||
| 208 | |||||||
| 209 | =head2 __download | ||||||
| 210 | |||||||
| 211 | This method is introduced with the 0.11 release of slackget10 and is the one used to emulate POE behaviour. | ||||||
| 212 | |||||||
| 213 | This method is here in order to simplify the migration to the new POE based architecture. | ||||||
| 214 | |||||||
| 215 | download() take only one argument : a file to download and it will call all needed InlineStates when it's possible. | ||||||
| 216 | |||||||
| 217 | =cut | ||||||
| 218 | |||||||
| 219 | sub __download { | ||||||
| 220 | 0 | 0 | my ($self,$file) = @_ ; | ||||
| 221 | } | ||||||
| 222 | |||||||
| 223 | |||||||
| 224 | =head1 AUTHOR | ||||||
| 225 | |||||||
| 226 |  DUPUIS Arnaud, C<<  | 
||||||
| 227 | |||||||
| 228 | =head1 BUGS | ||||||
| 229 | |||||||
| 230 | Please report any bugs or feature requests to | ||||||
| 231 |  C | 
||||||
| 232 |  L | 
||||||
| 233 | I will be notified, and then you'll automatically be notified of progress on | ||||||
| 234 | your bug as I make changes. | ||||||
| 235 | |||||||
| 236 | =head1 SUPPORT | ||||||
| 237 | |||||||
| 238 | You can find documentation for this module with the perldoc command. | ||||||
| 239 | |||||||
| 240 | perldoc Slackware::Slackget | ||||||
| 241 | |||||||
| 242 | |||||||
| 243 | You can also look for information at: | ||||||
| 244 | |||||||
| 245 | =over 4 | ||||||
| 246 | |||||||
| 247 | =item * Infinity Perl website | ||||||
| 248 | |||||||
| 249 |  L | 
||||||
| 250 | |||||||
| 251 | =item * slack-get specific website | ||||||
| 252 | |||||||
| 253 |  L | 
||||||
| 254 | |||||||
| 255 | =item * RT: CPAN's request tracker | ||||||
| 256 | |||||||
| 257 |  L | 
||||||
| 258 | |||||||
| 259 | =item * AnnoCPAN: Annotated CPAN documentation | ||||||
| 260 | |||||||
| 261 |  L | 
||||||
| 262 | |||||||
| 263 | =item * CPAN Ratings | ||||||
| 264 | |||||||
| 265 |  L | 
||||||
| 266 | |||||||
| 267 | =item * Search CPAN | ||||||
| 268 | |||||||
| 269 |  L | 
||||||
| 270 | |||||||
| 271 | =back | ||||||
| 272 | |||||||
| 273 | =head1 ACKNOWLEDGEMENTS | ||||||
| 274 | |||||||
| 275 | Thanks to Bertrand Dupuis (yes my brother) for his contribution to the documentation. | ||||||
| 276 | |||||||
| 277 | =head1 COPYRIGHT & LICENSE | ||||||
| 278 | |||||||
| 279 | Copyright 2005 DUPUIS Arnaud, All Rights Reserved. | ||||||
| 280 | |||||||
| 281 | This program is free software; you can redistribute it and/or modify it | ||||||
| 282 | under the same terms as Perl itself. | ||||||
| 283 | |||||||
| 284 | =cut | ||||||
| 285 | |||||||
| 286 | 1; # End of Slackware::Slackget::Network::Connection::HTTP |