Furl
view release on metacpan or search on metacpan
lib/Furl/HTTP.pm view on Meta::CPAN
sub _requires {
my($file, $feature, $library) = @_;
return if exists $INC{$file};
unless(eval { require $file }) {
if ($@ =~ /^Can't locate/) {
$library ||= do {
local $_ = $file;
s/ \.pm \z//xms;
s{/}{::}g;
$_;
};
Carp::croak(
"$feature requires $library, but it is not available."
. " Please install $library using your prefer CPAN client"
);
} else {
die $@;
}
}
}
# returns $scheme, $host, $port, $path_query
sub _parse_url {
my($self, $url) = @_;
$url =~ m{\A
([a-z]+) # scheme
://
(?:
([^/:@?]+) # user
:
([^/:@?]+) # password
@
)?
([^/:?]+) # host
(?: : (\d+) )? # port
(?: ( /? \? .* | / .*) )? # path_query
\z}xms or Carp::croak("Passed malformed URL: $url");
return( $1, $2, $3, $4, $5, $6 );
}
sub make_x_www_form_urlencoded {
my($self, $content) = @_;
my @params;
my @p = ref($content) eq 'HASH' ? %{$content}
: ref($content) eq 'ARRAY' ? @{$content}
: Carp::croak("Cannot coerce $content to x-www-form-urlencoded");
while ( my ( $k, $v ) = splice @p, 0, 2 ) {
foreach my $s($k, $v) {
utf8::downgrade($s); # will die in wide characters
# escape unsafe chars (defined by RFC 3986)
$s =~ s/ ([^A-Za-z0-9\-\._~]) / sprintf '%%%02X', ord $1 /xmsge;
}
push @params, "$k=$v";
}
return join( "&", @params );
}
sub env_proxy {
my $self = shift;
# Under CGI, bypass HTTP_PROXY as request sets it from Proxy header
# Note: This doesn't work on windows correctly.
local $ENV{HTTP_PROXY} if $ENV{REQUEST_METHOD};
$self->{proxy} = $ENV{http_proxy} || $ENV{HTTP_PROXY} || $self->{proxy};
$self->{no_proxy} = $ENV{NO_PROXY} || '';
$self;
}
sub request {
my $self = shift;
my %args = @_;
my $timeout_at = time + $self->{timeout};
my ($scheme, $username, $password, $host, $port, $path_query);
if (defined(my $url = $args{url})) {
($scheme, $username, $password, $host, $port, $path_query) = $self->_parse_url($url);
}
else {
($scheme, $host, $port, $path_query) = @args{qw/scheme host port path_query/};
if (not defined $host) {
Carp::croak("Missing host name in arguments");
}
}
if (not defined $scheme) {
$scheme = 'http';
} elsif($scheme ne 'http' && $scheme ne 'https') {
Carp::croak("Unsupported scheme: $scheme");
}
my $default_port = $scheme eq 'http'
? 80
: 443;
if(not defined $port) {
$port = $default_port;
}
if(not defined $path_query) {
$path_query = '/';
}
unless (substr($path_query, 0, 1) eq '/') {
$path_query = "/$path_query"; # Compensate for slash (?foo=bar => /?foo=bar)
}
# Note. '_' is a invalid character for URI, but some servers using fucking underscore for domain name. Then, I accept the '_' character for domain name.
if ($host =~ /[^A-Za-z0-9._-]/) {
_requires('Net/IDN/Encode.pm',
'Internationalized Domain Name (IDN)');
$host = Net::IDN::Encode::domain_to_ascii($host);
}
my $proxy = $self->{proxy};
my $no_proxy = $self->{no_proxy};
if ($proxy && $no_proxy) {
if ($self->match_no_proxy($no_proxy, $host)) {
undef $proxy;
}
}
local $SIG{PIPE} = 'IGNORE';
my $sock = $self->{connection_pool}->steal($host, $port);
my $in_keepalive;
if (defined $sock) {
( run in 0.486 second using v1.01-cache-2.11-cpan-71847e10f99 )