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
   "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
    header_format :Int = HEADERS_AS_ARRAYREF
        This option choose return value format of "$furl->request".

        This option allows HEADERS_NONE or HEADERS_AS_ARRAYREF.

        HEADERS_AS_ARRAYREF is a default value. This makes $headers as
        ArrayRef.

        HEADERS_NONE makes $headers as undef. Furl does not return parsing
        result of headers. You should take needed headers from
        special_headers.

  Instance Methods
   "$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 ...".

   "$furl->get($url :Str, $headers :ArrayRef[Str] ) :List"
    This is an easy-to-use alias to "request()".

   "$furl->head($url :Str, $headers :ArrayRef[Str] ) :List"
    This is an easy-to-use alias to "request()".

   "$furl->post($url :Str, $headers :ArrayRef[Str], $content :Any) :List"
    This is an easy-to-use alias to "request()".

   "$furl->put($url :Str, $headers :ArrayRef[Str], $content :Any) :List"
    This is an easy-to-use alias to "request()".

   "$furl->delete($url :Str, $headers :ArrayRef[Str] ) :List"
    This is an easy-to-use alias to "request()".

   "$furl->request_with_http_request($req :HTTP::Request) :List"
    This is an easy-to-use alias to "request()".

   "$furl->env_proxy()"
    Loads proxy settings from $ENV{HTTP_PROXY} and $ENV{NO_PROXY}.

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
        - 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 <tokuhirom AAJKLFJEF GMAIL COM>

    Fuji, Goro (gfx)

THANKS TO
    Kazuho Oku

    mala

    mattn

    lestrrat

    walf443

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.

