📄 useragent.pm
字号:
# Some sanity-checking... Carp::croak("A :content_file value can't be undef") unless defined $arg; Carp::croak("A :content_file value can't be a reference") if ref $arg; Carp::croak("A :content_file value can't be \"\"") unless length $arg; } elsif ($args->[$i] eq ':read_size_hint') { $size = $args->[$i + 1]; # Bother checking it? } else { next; } splice @$args, $i, 2; $i -= 2; } # And return a suitable suffix-list for request(REQ,...) return unless defined $arg; return $arg, $size if defined $size; return $arg;}sub progress { my($self, $status, $response) = @_; # subclasses might override this}## This whole allow/forbid thing is based on man 1 at's way of doing things.#sub is_protocol_supported{ my($self, $scheme) = @_; if (ref $scheme) { # assume we got a reference to an URI object $scheme = $scheme->scheme; } else { Carp::croak("Illegal scheme '$scheme' passed to is_protocol_supported") if $scheme =~ /\W/; $scheme = lc $scheme; } my $x; if(ref($self) and $x = $self->protocols_allowed) { return 0 unless grep lc($_) eq $scheme, @$x; } elsif (ref($self) and $x = $self->protocols_forbidden) { return 0 if grep lc($_) eq $scheme, @$x; } local($SIG{__DIE__}); # protect against user defined die handlers $x = LWP::Protocol::implementor($scheme); return 1 if $x and $x ne 'LWP::Protocol::nogo'; return 0;}sub protocols_allowed { shift->_elem('protocols_allowed' , @_) }sub protocols_forbidden { shift->_elem('protocols_forbidden' , @_) }sub requests_redirectable { shift->_elem('requests_redirectable', @_) }sub redirect_ok{ # RFC 2616, section 10.3.2 and 10.3.3 say: # If the 30[12] status code is received in response to a request other # than GET or HEAD, the user agent MUST NOT automatically redirect the # request unless it can be confirmed by the user, since this might # change the conditions under which the request was issued. # Note that this routine used to be just: # return 0 if $_[1]->method eq "POST"; return 1; my($self, $new_request, $response) = @_; my $method = $response->request->method; return 0 unless grep $_ eq $method, @{ $self->requests_redirectable || [] }; if ($new_request->url->scheme eq 'file') { $response->header("Client-Warning" => "Can't redirect to a file:// URL!"); return 0; } # Otherwise it's apparently okay... return 1;}sub credentials{ my($self, $netloc, $realm, $uid, $pass) = @_; @{ $self->{'basic_authentication'}{lc($netloc)}{$realm} } = ($uid, $pass);}sub get_basic_credentials{ my($self, $realm, $uri, $proxy) = @_; return if $proxy; my $host_port = lc($uri->host_port); if (exists $self->{'basic_authentication'}{$host_port}{$realm}) { return @{ $self->{'basic_authentication'}{$host_port}{$realm} }; } return (undef, undef);}sub agent { my $self = shift; my $old = $self->{agent}; if (@_) { my $agent = shift; $agent .= $self->_agent if $agent && $agent =~ /\s+$/; $self->{agent} = $agent; } $old;}sub _agent { "libwww-perl/$LWP::VERSION" }sub timeout { shift->_elem('timeout', @_); }sub from { shift->_elem('from', @_); }sub parse_head { shift->_elem('parse_head', @_); }sub max_size { shift->_elem('max_size', @_); }sub max_redirect { shift->_elem('max_redirect', @_); }sub cookie_jar { my $self = shift; my $old = $self->{cookie_jar}; if (@_) { my $jar = shift; if (ref($jar) eq "HASH") { require HTTP::Cookies; $jar = HTTP::Cookies->new(%$jar); } $self->{cookie_jar} = $jar; } $old;}sub default_headers { my $self = shift; my $old = $self->{def_headers} ||= HTTP::Headers->new; if (@_) { $self->{def_headers} = shift; } return $old;}sub default_header { my $self = shift; return $self->default_headers->header(@_);}sub conn_cache { my $self = shift; my $old = $self->{conn_cache}; if (@_) { my $cache = shift; if (ref($cache) eq "HASH") { require LWP::ConnCache; $cache = LWP::ConnCache->new(%$cache); } $self->{conn_cache} = $cache; } $old;}# depreciatedsub use_eval { shift->_elem('use_eval', @_); }sub use_alarm{ Carp::carp("LWP::UserAgent->use_alarm(BOOL) is a no-op") if @_ > 1 && $^W; "";}sub clone{ my $self = shift; my $copy = bless { %$self }, ref $self; # copy most fields # elements that are references must be handled in a special way $copy->{'proxy'} = { %{$self->{'proxy'}} }; $copy->{'no_proxy'} = [ @{$self->{'no_proxy'}} ]; # copy array # remove reference to objects for now delete $copy->{cookie_jar}; delete $copy->{conn_cache}; $copy;}sub mirror{ my($self, $url, $file) = @_; LWP::Debug::trace('()'); my $request = HTTP::Request->new('GET', $url); if (-e $file) { my($mtime) = (stat($file))[9]; if($mtime) { $request->header('If-Modified-Since' => HTTP::Date::time2str($mtime)); } } my $tmpfile = "$file-$$"; my $response = $self->request($request, $tmpfile); if ($response->is_success) { my $file_length = (stat($tmpfile))[7]; my($content_length) = $response->header('Content-length'); if (defined $content_length and $file_length < $content_length) { unlink($tmpfile); die "Transfer truncated: " . "only $file_length out of $content_length bytes received\n"; } elsif (defined $content_length and $file_length > $content_length) { unlink($tmpfile); die "Content-length mismatch: " . "expected $content_length bytes, got $file_length\n"; } else { # OK if (-e $file) { # Some dosish systems fail to rename if the target exists chmod 0777, $file; unlink $file; } rename($tmpfile, $file) or die "Cannot rename '$tmpfile' to '$file': $!\n"; if (my $lm = $response->last_modified) { # make sure the file has the same last modification time utime $lm, $lm, $file; } } } else { unlink($tmpfile); } return $response;}sub proxy{ my $self = shift; my $key = shift; LWP::Debug::trace("$key @_"); return map $self->proxy($_, @_), @$key if ref $key; my $old = $self->{'proxy'}{$key}; $self->{'proxy'}{$key} = shift if @_; return $old;}sub env_proxy { my ($self) = @_; my($k,$v); while(($k, $v) = each %ENV) { if ($ENV{REQUEST_METHOD}) { # Need to be careful when called in the CGI environment, as # the HTTP_PROXY variable is under control of that other guy. next if $k =~ /^HTTP_/; $k = "HTTP_PROXY" if $k eq "CGI_HTTP_PROXY"; } $k = lc($k); next unless $k =~ /^(.*)_proxy$/; $k = $1; if ($k eq 'no') { $self->no_proxy(split(/\s*,\s*/, $v)); } else { $self->proxy($k, $v); } }}sub no_proxy { my($self, @no) = @_; if (@no) { push(@{ $self->{'no_proxy'} }, @no); } else { $self->{'no_proxy'} = []; }}# Private method which returns the URL of the Proxy configured for this# URL, or undefined if none is configured.sub _need_proxy{ my($self, $url) = @_; $url = $HTTP::URI_CLASS->new($url) unless ref $url; my $scheme = $url->scheme || return; if (my $proxy = $self->{'proxy'}{$scheme}) { if (@{ $self->{'no_proxy'} }) { if (my $host = eval { $url->host }) { for my $domain (@{ $self->{'no_proxy'} }) { if ($host =~ /\Q$domain\E$/) { LWP::Debug::trace("no_proxy configured"); return; } } } } LWP::Debug::debug("Proxied to $proxy"); return $HTTP::URI_CLASS->new($proxy); } LWP::Debug::debug('Not proxied'); undef;}sub _new_response { my($request, $code, $message) = @_; my $response = HTTP::Response->new($code, $message); $response->request($request); $response->header("Client-Date" => HTTP::Date::time2str(time)); $response->header("Client-Warning" => "Internal response"); $response->header("Content-Type" => "text/plain"); $response->content("$code $message\n"); return $response;}1;__END__=head1 NAMELWP::UserAgent - Web user agent class=head1 SYNOPSIS require LWP::UserAgent; my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->env_proxy; my $response = $ua->get('http://search.cpan.org/'); if ($response->is_success) { print $response->content; # or whatever } else { die $response->status_line; }=head1 DESCRIPTIONThe C<LWP::UserAgent> is a class implementing a web user agent.C<LWP::UserAgent> objects can be used to dispatch web requests.In normal use the application creates an C<LWP::UserAgent> object, andthen configures it with values for timeouts, proxies, name, etc. Itthen creates an instance of C<HTTP::Request> for the request thatneeds to be performed. This request is then passed to one of therequest method the UserAgent, which dispatches it using the relevantprotocol, and returns a C<HTTP::Response> object. There areconvenience methods for sending the most common request types: get(),head() and post(). When using these methods then the creation of therequest object is hidden as shown in the synopsis above.The basic approach of the library is to use HTTP style communicationfor all protocol schemes. This means that you will constructC<HTTP::Request> objects and receive C<HTTP::Response> objects evenfor non-HTTP resources like I<gopher> and I<ftp>. In order to achieveeven more similarity to HTTP style communications, gopher menus andfile directories are converted to HTML documents.=head1 CONSTRUCTOR METHODSThe following constructor methods are available:=over 4=item $ua = LWP::UserAgent->new( %options )This method constructs a new C<LWP::UserAgent> object and returns it.Key/value pair arguments may be provided to set up the initial state.The following options correspond to attribute methods described below: KEY DEFAULT ----------- -------------------- agent "libwww-perl/#.##" from undef conn_cache undef cookie_jar undef default_headers HTTP::Headers->new max_size undef max_redirect 7 parse_head 1 protocols_allowed undef protocols_forbidden undef requests_redirectable ['GET', 'HEAD'] timeout 180The following additional options are also accepted: If theC<env_proxy> option is passed in with a TRUE value, then proxysettings are read from environment variables (see env_proxy() methodbelow). If the C<keep_alive> option is passed in, then aC<LWP::ConnCache> is set up (see conn_cache() method below). TheC<keep_alive> value is passed on as the C<total_capacity> for theconnection cache.=item $ua->cloneReturns a copy of the LWP::UserAgent object.=back=head1 ATTRIBUTESThe settings of the configuration attributes modify the behaviour of theC<LWP::UserAgent> when it dispatches requests. Most of these can alsobe initialized by options passed to the constructor method.The following attributes methods are provided. The attribute value isleft unchanged if no argument is given. The return value from eachmethod is the old attribute value.=over=item $ua->agent=item $ua->agent( $product_id )Get/set the product token that is used to identify the user agent onthe network. The agent value is sent as the "User-Agent" header inthe requests. The default is the string returned by the _agent()method (see below).
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -