Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
pretty fast http client library for perl5
Perl

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
author
benchmark
example
lib
picohttpparser @ 4117b02
t
xs
xt
.gitignore
.gitmodules
.shipit
Changes
MANIFEST
MANIFEST.SKIP
Makefile.PL
README.mkdn
TODO

README.mkdn

NAME

Furl - Lightning-fast URL fetcher

SYNOPSIS

use Furl;

my $furl = Furl->new(
    agent   => 'MyGreatUA/2.0',
    timeout => 10,
);

my ($code, $msg, $headers, $body) = $furl->request(
    method => 'GET',
    host   => 'example.com',
    port   => 80,
    path   => '/'
);
# or
my ($code, $msg, $headers, $body) = $furl->get('http://example.com/');
my ($code, $msg, $headers, $body) = $furl->post(
    'http://example.com/', # URL
    [...],                 # headers
    [ foo => 'bar' ],      # form data (HashRef/FileHandle are also okay)
);

# Accept-Encoding is supported but optional
$furl = Furl->new(
    headers => [ 'Accept-Encoding' => 'gzip' ],
);
my $body = $furl->get('http://example.com/some/compressed');

DESCRIPTION

Furl is yet another HTTP client library. LWP is the de facto standard HTTP client for Perl5, but it is too slow for some critical jobs, and too complex for weekend hacking. Furl resolves these issues. Enjoy it!

This library is an alpha software. Any API may change without notice.

INTERFACE

Class Methods

C<< Furl->new(%args | \%args) :Furl >>

Creates and returns a new Furl client with %args. Dies on errors.

%args might be:

  • agent :Str = "Furl/$VERSION"

  • timeout :Int = 10

  • max_redirects :Int = 7

  • proxy :Str

  • no_proxy :Str

  • headers :ArrayRef

Instance Methods

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

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

%args might be:

  • scheme :Str = "http"

Protocol scheme. May be http or https.

  • host :Str

Server host to connect.

You must specify at least host or url.

  • port :Int = 80

Server port to connect. The default is 80 on scheme => 'http', or 443 on scheme => 'https'.

  • path_query :Str = "/"

Path and query to request.

  • url :Str

URL to request.

You can use url instead of scheme, host, port and path_query.

  • headers :ArrayRef

HTTP request headers. e.g. headers => [ 'Accept-Encoding' => 'gzip' ].

  • content : Str | ArrayRef[Str] | HashRef[Str] | FileHandle

Content to request.

You must encode all the queries or this method will die, saying Wide character in ....

C<< $furl->get($url :Str, $headers :ArrayRef[Str] ) :List >>

This is an easy-to-use alias to request().

C<< $furl->head($url :Str, $headers :ArrayRef[Str] ) :List >>

This is an easy-to-use alias to request().

C<< $furl->post($url :Str, $headers :ArrayRef[Str], $content :Any) :List >>

This is an easy-to-use alias to request().

C<< $furl->put($url :Str, $headers :ArrayRef[Str], $content :Any) :List >>

This is an easy-to-use alias to request().

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

This is an easy-to-use alias to request().

C<< $furl->request_with_http_request($req :HTTP::Request) :List >>

This is an easy-to-use alias to request().

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

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

Utilities

C<< Furl::Util::header_get(\@headers, $name :Str) :Maybe[Str] >>

This is equivalent to Plack::Util::header_get().

INTEGRATE WITH HTTP::Response

Some useful libraries require HTTP::Response instances for their arguments. You can easily create its instance from the result of request() and other HTTP request methods.

my $res = HTTP::Response->new($furl->get($url));

PROJECT POLICY

  • Why IO::Socket::SSL?

Net::SSL is not well documented.

  • 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.

  • What operating systems are supported?

Linux 2.6 or higher, OSX Tiger or higher, Windows XP or higher.

And other operating systems will be supported if you send a patch.

  • Why doesn't Furl support chunked upload?

There are reasons why chunked POST/PUTs should not be used in general.

First, you cannot send chunked requests unless the peer server at the other end of the established TCP connection is known to be a HTTP/1.1 server.

Second, HTTP/1.1 servers disconnect their persistent connection quite quickly (compared to the time they wait for the first request), so it is not a good idea to post non-idempotent requests (e.g. POST, PUT, etc.) as a succeeding request over persistent connections.

These facts together makes using chunked requests virtually impossible (unless you know that the server supports HTTP/1.1), and this is why we decided that supporting the feature is NOT of high priority.

FAQ

  • How do you build the response content as it arrives?

You can use IO::Callback for this purpose.

my $fh = IO::Callback->new(
    '<',
    sub {
        my $x = shift @data;
        $x ? "-$x" : undef;
    }
);
my ( $code, $msg, $headers, $content ) =
  $furl->put( "http://127.0.0.1:$port/", [ 'Content-Length' => $len ], $fh,
  );
  • How do you use cookie_jar?

Furl does not directly support the cookie_jar option available in LWP. You can use HTTP::Cookies, HTTP::Request, HTTP::Response like following.

my $f = Furl->new();
my $cookies = HTTP::Cookies->new();
my $req = HTTP::Request->new(...);
$cookies->add_cookie_header($req);
my $res = HTTP::Response->new($f->request_with_http_request($req));
$cookies->extract_cookies($res);
# and use $res.
  • How do you use gzip/deflate compressed communication?

Add an Accept-Encoding header to your request. Furl inflates response bodies transparently according to the Content-Encoding response header.

  • How do you use mutipart/form-data?

You can use multipart/form-data with HTTP::Request::Common.

use HTTP::Request::Common;

my $furl = Furl->new();
$req = POST 'http://www.perl.org/survey.cgi',
  Content_Type => 'form-data',
  Content      => [
    name   => 'Hiromu Tokunaga',
    email  => 'tokuhirom@example.com',
    gender => 'F',
    born   => '1978',
    init   => ["$ENV{HOME}/.profile"],
  ];
$furl->request_with_http_request($req);

Native multipart/form-data support for Furl is available if you can send a patch for me.

  • How do you use Keep-Alive and what happens on the HEAD method?

Furl supports HTTP/1.1, hence Keep-Alive. However, if you use the HEAD method, the connection is closed immediately.

RFC 2616 section 9.4 says:

The HEAD method is identical to GET except that the server MUST NOT
return a message-body in the response.

Some web applications, however, returns message bodies on the HEAD method, which might confuse Keep-Alive processes, so Furl closes connection in such cases.

Anyway, the HEAD method is not so useful nowadays. The GET method and If-Modified-Sinse are more suitable to cache HTTP contents.

TODO

- AnyEvent::Furl?
- use HTTP::Response::Parser
- PP version(by HTTP::Respones::Parser)
- ipv6 support
- better docs for NO_PROXY

OPTIONAL FEATURES

Internationalized Domain Name (IDN)

This feature requires Net::IDN::Encode.

SSL

This feature requires IO::Socket::SSL.

Content-Encoding (deflate, gzip)

This feature requires Compress::Raw::Zlib.

DEVELOPMENT

To setup your environment:

$ git clone http://github.com/tokuhirom/p5-Furl.git
$ cd p5-Furl

To get picohttpparser:

$ git submodule init
$ git submodule update

$ perl Makefile.PL
$ make
$ sudo make install

HOW TO CONTRIBUTE

Please send the pull-req via http://github.com/tokuhirom/p5-Furl/.

AUTHOR

Tokuhiro Matsuno

Fuji, Goro (gfx)

THANKS TO

Kazuho Oku

mala

mattn

lestrrat

SEE ALSO

LWP

HTTP specs: http://www.w3.org/Protocols/HTTP/1.0/spec.html http://www.w3.org/Protocols/HTTP/1.1/spec.html

LICENSE

Copyright (C) Tokuhiro Matsuno.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

Something went wrong with that request. Please try again.