Furl

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN


    - Added Furl::Response#decoded_content
      (xaicron++)
    - Added Furl::Headers#clone
      (tokuhirom)

2.01 2013-01-23T19:17:47


    - pass SSL_verifycn_name on connecting ssl over proxy.
      IO::Socket::SSL detects host name from PeerHost, but it can't when user
      is using proxy.
      (aska++)
    - SSL_verifycn_scheme is not required if skipping verification
      if skip verification, does not requires SSL_verifycn_scheme
      (kazeburo++)


2.00 2013-01-23T15:46:46

    *** VERY IMPORTANT INCOMPATIBLE CHANGE ***

Changes  view on Meta::CPAN

      (gfx)

1.02 2013-01-07

    - Use Mozilla::CA if SSL_ca_file and SSL_ca_path is not set.
      This behavior respects LWP::Protocol::https.
      (tokuhirom)

1.01 2013-01-03

    - added `ssl_opts` option to configuring IO::Socket::SSL
      (gfx)

1.00 2012-10-19

    - Bump up version

0.42 2012-10-15

    [INCOMPATIBLE CHANGE]
    - Furl::HTTP is no longer reading Furl.pm.

META.json  view on Meta::CPAN

            "URI" : "0",
            "WWW::Curl::Easy" : "4.14",
            "autodie" : "0",
            "parent" : "0"
         }
      },
      "runtime" : {
         "recommends" : {
            "Compress::Raw::Zlib" : "0",
            "HTTP::CookieJar" : "0",
            "IO::Socket::SSL" : "0",
            "Net::IDN::Encode" : "0"
         },
         "requires" : {
            "Class::Accessor::Lite" : "0",
            "Encode" : "0",
            "HTTP::Parser::XS" : "0.11",
            "MIME::Base64" : "0",
            "Mozilla::CA" : "0",
            "Scalar::Util" : "0",
            "Socket" : "0",

META.yml  view on Meta::CPAN

    file: lib/Furl/Headers.pm
  Furl::Request:
    file: lib/Furl/Request.pm
  Furl::Response:
    file: lib/Furl/Response.pm
  Furl::ZlibStream:
    file: lib/Furl/ZlibStream.pm
recommends:
  Compress::Raw::Zlib: '0'
  HTTP::CookieJar: '0'
  IO::Socket::SSL: '0'
  Net::IDN::Encode: '0'
requires:
  Class::Accessor::Lite: '0'
  Encode: '0'
  HTTP::Parser::XS: '0.11'
  MIME::Base64: '0'
  Mozilla::CA: '0'
  Scalar::Util: '0'
  Socket: '0'
  Time::HiRes: '0'

README.md  view on Meta::CPAN

### `$furl->delete($url :Str, $headers :ArrayRef[Str] )`

This is an easy-to-use alias to `request()`, sending the `DELETE` method.

### `$furl->env_proxy()`

Loads proxy settings from `$ENV{HTTP_PROXY}` and `$ENV{NO_PROXY}`.

# TIPS

- [IO::Socket::SSL](https://metacpan.org/pod/IO%3A%3ASocket%3A%3ASSL) preloading

    Furl interprets the `timeout` argument as the maximum time the module is permitted to spend before returning an error.

    The module also lazy-loads [IO::Socket::SSL](https://metacpan.org/pod/IO%3A%3ASocket%3A%3ASSL) when an HTTPS request is being issued for the first time. Loading the module usually takes ~0.1 seconds.

    The time spent for loading the SSL module may become an issue in case you want to impose a very small timeout value for connection establishment. In such case, users are advised to preload the SSL module explicitly.

# FAQ

- Does Furl depends on XS modules?

    No. Although some optional features require XS modules, basic features are
    available without XS modules.

README.md  view on Meta::CPAN

                }
                $received_size += length($buf);
                $content .= $buf;
                $next_update = $bar->update($received_size)
                if $received_size >= $next_update;
            }
        );

- HTTPS requests claims warnings!

    When you make https requests, IO::Socket::SSL may complain about it like:

        *******************************************************************
         Using the default of SSL_verify_mode of SSL_VERIFY_NONE for client
         is depreciated! Please set SSL_verify_mode to SSL_VERIFY_PEER
         together with SSL_ca_file|SSL_ca_path for verification.
         If you really don't want to verify the certificate and keep the
         connection open to Man-In-The-Middle attacks please set
         SSL_verify_mode explicitly to SSL_VERIFY_NONE in your application.
        *******************************************************************

    You should set `SSL_verify_mode` explicitly with Furl's `ssl_opts`.

        use IO::Socket::SSL;

        my $ua = Furl->new(
            ssl_opts => {
                SSL_verify_mode => SSL_VERIFY_PEER(),
            },
        );

    See [IO::Socket::SSL](https://metacpan.org/pod/IO%3A%3ASocket%3A%3ASSL) for details.

# AUTHOR

Tokuhiro Matsuno <tokuhirom@gmail.com>

Fuji, Goro (gfx)

# THANKS TO

Kazuho Oku

README.md  view on Meta::CPAN

walf443

lestrrat

audreyt

# SEE ALSO

[LWP](https://metacpan.org/pod/LWP)

[IO::Socket::SSL](https://metacpan.org/pod/IO%3A%3ASocket%3A%3ASSL)

[Furl::HTTP](https://metacpan.org/pod/Furl%3A%3AHTTP)

[Furl::Response](https://metacpan.org/pod/Furl%3A%3AResponse)

# LICENSE

Copyright (C) Tokuhiro Matsuno.

This library is free software; you can redistribute it and/or modify

cpanfile  view on Meta::CPAN

requires 'Encode';
requires 'Scalar::Util';
requires 'Socket';
requires 'Time::HiRes';

suggests 'HTTP::Headers'; # Furl::Headers
suggests 'HTTP::Request'; # Furl::Request
suggests 'HTTP::Response'; # Furl::Response

recommends 'Net::IDN::Encode';    # for International Domain Name
recommends 'IO::Socket::SSL';     # for SSL
recommends 'Compress::Raw::Zlib'; # for Content-Encoding
recommends 'HTTP::CookieJar';

on test => sub {
    requires 'Test::More' => 0.96;    # done_testing, subtest
    requires 'Test::TCP'  => '2.11';
    requires 'Test::Requires';
    requires 'File::Temp';
    suggests 'Test::Fake::HTTPD';
    suggests 'HTTP::Proxy';

lib/Furl.pm  view on Meta::CPAN

This is an easy-to-use alias to C<request()>, sending the C<DELETE> method.

=head3 C<< $furl->env_proxy() >>

Loads proxy settings from C<< $ENV{HTTP_PROXY} >> and C<< $ENV{NO_PROXY} >>.

=head1 TIPS

=over 4

=item L<IO::Socket::SSL> preloading

Furl interprets the C<timeout> argument as the maximum time the module is permitted to spend before returning an error.

The module also lazy-loads L<IO::Socket::SSL> when an HTTPS request is being issued for the first time. Loading the module usually takes ~0.1 seconds.

The time spent for loading the SSL module may become an issue in case you want to impose a very small timeout value for connection establishment. In such case, users are advised to preload the SSL module explicitly.

=back

=head1 FAQ

=over 4

=item Does Furl depends on XS modules?

lib/Furl.pm  view on Meta::CPAN

            }
            $received_size += length($buf);
            $content .= $buf;
            $next_update = $bar->update($received_size)
            if $received_size >= $next_update;
        }
    );

=item HTTPS requests claims warnings!

When you make https requests, IO::Socket::SSL may complain about it like:

    *******************************************************************
     Using the default of SSL_verify_mode of SSL_VERIFY_NONE for client
     is depreciated! Please set SSL_verify_mode to SSL_VERIFY_PEER
     together with SSL_ca_file|SSL_ca_path for verification.
     If you really don't want to verify the certificate and keep the
     connection open to Man-In-The-Middle attacks please set
     SSL_verify_mode explicitly to SSL_VERIFY_NONE in your application.
    *******************************************************************

You should set C<SSL_verify_mode> explicitly with Furl's C<ssl_opts>.

    use IO::Socket::SSL;

    my $ua = Furl->new(
        ssl_opts => {
            SSL_verify_mode => SSL_VERIFY_PEER(),
        },
    );

See L<IO::Socket::SSL> for details.

=back

=head1 AUTHOR

Tokuhiro Matsuno E<lt>tokuhirom@gmail.comE<gt>

Fuji, Goro (gfx)

=head1 THANKS TO

lib/Furl.pm  view on Meta::CPAN

walf443

lestrrat

audreyt

=head1 SEE ALSO

L<LWP>

L<IO::Socket::SSL>

L<Furl::HTTP>

L<Furl::Response>

=head1 LICENSE

Copyright (C) Tokuhiro Matsuno.

This library is free software; you can redistribute it and/or modify

lib/Furl/HTTP.pm  view on Meta::CPAN

    my $iaddr = $self->{inet_aton}->($host, $timeout)
        or return (undef, $!);
    pack_sockaddr_in($port, $iaddr);
}

sub _ssl_opts {
    my $self = shift;
    my $ssl_opts = $self->{ssl_opts};
    unless (exists $ssl_opts->{SSL_verify_mode}) {
        # set SSL_VERIFY_PEER as default.
        $ssl_opts->{SSL_verify_mode}     = IO::Socket::SSL::SSL_VERIFY_PEER();
        unless (exists $ssl_opts->{SSL_verifycn_scheme}) {
            $ssl_opts->{SSL_verifycn_scheme} = 'www'
        }
    }
    if ($ssl_opts->{SSL_verify_mode}) {
        unless (exists $ssl_opts->{SSL_ca_file} || exists $ssl_opts->{SSL_ca_path}) {
            require Mozilla::CA;
            $ssl_opts->{SSL_ca_file} = Mozilla::CA::SSL_ca_file();
        }
    }

lib/Furl/HTTP.pm  view on Meta::CPAN


    my ($sock, $err_reason) = $self->connect($host, $port, $timeout_at);
    return (undef, $err_reason)
        unless $sock;

    my $timeout = $timeout_at - time;
    return (undef, "Cannot create SSL connection: timeout")
        if $timeout <= 0;

    my $ssl_opts = $self->_ssl_opts;
    IO::Socket::SSL->start_SSL(
        $sock,
        PeerHost => $host,
        PeerPort => $port,
        Timeout  => $timeout,
        %$ssl_opts,
    ) or return (undef, "Cannot create SSL connection: " . IO::Socket::SSL::errstr());
    _set_sockopts($sock);
    $sock;
}

sub connect_ssl_over_proxy {
    my ($self, $proxy_host, $proxy_port, $host, $port, $timeout_at, $proxy_authorization) = @_;
    _requires('IO/Socket/SSL.pm', 'SSL');

    my $sock = $self->connect($proxy_host, $proxy_port, $timeout_at);

lib/Furl/HTTP.pm  view on Meta::CPAN

    }

    my $timeout = $timeout_at - time;
    return (undef, "Cannot start SSL connection: timeout")
        if $timeout_at <= 0;

    my $ssl_opts = $self->_ssl_opts;
    unless (exists $ssl_opts->{SSL_verifycn_name}) {
        $ssl_opts->{SSL_verifycn_name} = $host;
    }
    IO::Socket::SSL->start_SSL(
        $sock,
        PeerHost => $host,
        PeerPort => $port,
        Timeout  => $timeout,
        %$ssl_opts
    ) or return (undef, "Cannot start SSL connection: " . IO::Socket::SSL::errstr());
    _set_sockopts($sock); # just in case (20101118 kazuho)
    $sock;
}

sub _read_body_chunked {
    my ($self, $sock, $res_content, $rest_header, $timeout_at) = @_;

    my $buf = $rest_header;
  READ_LOOP: while (1) {
        if (

lib/Furl/HTTP.pm  view on Meta::CPAN

sub _strerror_or_timeout {
    $! != 0 ? "$!" : 'timeout';
}

sub _set_sockopts {
    my $sock = shift;

    setsockopt( $sock, IPPROTO_TCP, TCP_NODELAY, 1 )
        or Carp::croak("Failed to setsockopt(TCP_NODELAY): $!");
    if (WIN32) {
        if (ref($sock) ne 'IO::Socket::SSL') {
            my $tmp = 1;
            ioctl( $sock, 0x8004667E, \$tmp )
                or Carp::croak("Cannot set flags for the socket: $!");
        }
    } else {
        my $flags = fcntl( $sock, F_GETFL, 0 )
            or Carp::croak("Cannot get flags for the socket: $!");
        $flags = fcntl( $sock, F_SETFL, $flags | O_NONBLOCK )
            or Carp::croak("Cannot set flags for the socket: $!");
    }

lib/Furl/HTTP.pm  view on Meta::CPAN

A callback function to override the default address resolution logic. Takes three arguments: ($hostname, $port, $timeout_in_seconds) and returns: ($sockaddr, $errReason).  If the returned $sockaddr is undef, then the resolution is considered as a fai...

=item inet_aton :CodeRef

Deprecated.  New applications should use B<get_address> instead.

A callback function to customize name resolution. Takes two arguments: ($hostname, $timeout_in_seconds). If omitted, Furl calls L<Socket::inet_aton>.

=item ssl_opts :HashRef

SSL configuration used on https requests, passed directly to C<< IO::Socket::SSL->new() >>,

for example:

    use IO::Socket::SSL;

    my $ua = Furl::HTTP->new(
        ssl_opts => {
            SSL_verify_mode => SSL_VERIFY_PEER(),
        },
    });

See L<IO::Socket::SSL> for details.

=back

=head2 Instance Methods

=head3 C<< $furl->request(%args) :($protocol_minor_version, $code, $msg, \@headers, $body) >>

Sends an HTTP request to a specified URL and returns a protocol minor version,
status code, status message, response headers, response body respectively.

lib/Furl/HTTP.pm  view on Meta::CPAN

This is an easy-to-use alias to C<request()>, sending the C<PUT> method.

=head3 C<< $furl->delete($url :Str, $headers :ArrayRef[Str] ) >>

This is an easy-to-use alias to C<request()>, sending the C<DELETE> method.

=head1 FAQ

=over 4

=item Why IO::Socket::SSL?

Net::SSL is not well documented.

=item Why is env_proxy optional?

Environment variables are highly dependent on each users' environment,
and we think it may confuse users when something doesn't go right.

=item What operating systems are supported?

lib/Furl/HTTP.pm  view on Meta::CPAN

    - better docs for NO_PROXY

=head1 OPTIONAL FEATURES

=head2 Internationalized Domain Name (IDN)

This feature requires Net::IDN::Encode.

=head2 SSL

This feature requires IO::Socket::SSL.

=head2 Content-Encoding (deflate, gzip)

This feature requires Compress::Raw::Zlib.

=head1 DEVELOPMENT

To setup your environment:

    $ git clone http://github.com/tokuhirom/Furl.git

t/00_compile.t  view on Meta::CPAN

use strict;
use Test::More tests => 1;

BEGIN { use_ok 'Furl' }
diag "Perl/$^V";
diag "Furl/$Furl::VERSION";

for my $optional(qw( Net::IDN::Encode IO::Socket::SSL Compress::Raw::Zlib )) {
    eval qq{ require $optional };
    diag $optional . '/' . ($optional->VERSION || '(not installed)');
}

xt/200_online/04_ssl.t  view on Meta::CPAN

use strict;
use warnings;
use utf8;
use Test::More;
use Test::Requires qw(Plack::Request HTTP::Body), qw(IO::Socket::SSL);
use Furl;
use IO::Socket::SSL;
use FindBin;
use lib "$FindBin::Bin/../..";
use t::Util;

# this test moved to xt/ since mixi's ssl sucks.
# ref. http://www.machu.jp/diary/20080918.html#p01

skip_if_offline();

my $furl = Furl->new();

xt/200_online/05_connect_error.t  view on Meta::CPAN

use strict;
use warnings;

use Furl::HTTP;
use Test::More;
use Test::Requires qw(Plack::Request HTTP::Body), qw(IO::Socket::SSL);
use Time::HiRes qw(time);

my $n = shift(@ARGV) || 2;

# TODO add proxy tests

note 'name resolution error';
{
    my $furl = Furl::HTTP->new(timeout => 60);
    my (undef, $code, $msg, $headers, $content) =

xt/200_online/05_connect_error.t  view on Meta::CPAN

    like $msg, qr/Internal Response: Cannot resolve host name: a/;
    is ref($headers), 'ARRAY';
    ok $content, "content: $content";
}

note 'refused error';
{
    my $furl = Furl::HTTP->new(
        timeout => 60,
        ssl_opts => {
            SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_PEER(),
        },
    );
    for my $scheme (qw(http https)) {
        for (1 .. $n) {
            my $start_at = time;
            my (undef, $code, $msg, $headers, $content) =
                $furl->request(
                    host       => '255.255.255.255',
                    port       => 80,
                    scheme     => $scheme,

xt/200_online/05_connect_error.t  view on Meta::CPAN

                like $msg, qr/Internal Response: (Cannot connect to 255.255.255.255:80:|Cannot create SSL connection:)/;
            }
            is ref($headers), 'ARRAY';
            ok $content, "content: $content";
            ok $elapsed < 0.5 unless Furl::HTTP::WIN32 && $scheme eq 'https';
        }
    }
}

note 'timeout error';
# Timeout parameter of IO::Socket::SSL does not seem to be accurate, so only test http
for my $scheme (qw(http)) {
    for my $timeout (1.5, 4, 8) {
        my $furl = Furl::HTTP->new(timeout => $timeout);
        my $start_at = time;
        my (undef, $code, $msg, $headers, $content) =
            $furl->request(
                host       => 'google.com',
                port       => 81,
                scheme     => $scheme,
                path_query => '/foo',

xt/200_online/07_ssl_shutdown.t  view on Meta::CPAN

#!perl
use strict;
use warnings;
use Test::More;
use Furl;
use IO::Socket::SSL;

my $res = Furl->new(
    ssl_opts => {
        SSL_verify_mode => SSL_VERIFY_PEER(),
    },
)->get('https://foursquare.com/login');
ok $res->is_success, 'SSL get';
done_testing;



( run in 0.816 second using v1.01-cache-2.11-cpan-fd5d4e115d8 )