.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.42) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Furl::HTTP 3pm" .TH Furl::HTTP 3pm "2022-02-20" "perl v5.34.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Furl::HTTP \- Low level interface to Furl .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use Furl; \& \& my $furl = Furl::HTTP\->new( \& agent => \*(AqMyGreatUA/2.0\*(Aq, \& timeout => 10, \& ); \& \& my ($minor_version, $code, $msg, $headers, $body) = $furl\->request( \& method => \*(AqGET\*(Aq, \& host => \*(Aqexample.com\*(Aq, \& port => 80, \& path_query => \*(Aq/\*(Aq \& ); \& # or \& \& # Accept\-Encoding is supported but optional \& $furl = Furl\->new( \& headers => [ \*(AqAccept\-Encoding\*(Aq => \*(Aqgzip\*(Aq ], \& ); \& my $body = $furl\->get(\*(Aqhttp://example.com/some/compressed\*(Aq); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" Furl is yet another \s-1HTTP\s0 client library. \s-1LWP\s0 is the de facto standard \s-1HTTP\s0 client for Perl 5, but it is too slow for some critical jobs, and too complex for weekend hacking. Furl resolves these issues. Enjoy it! .SH "INTERFACE" .IX Header "INTERFACE" .SS "Class Methods" .IX Subsection "Class Methods" \fI\f(CI\*(C`Furl::HTTP\->new(%args | \e%args) :Furl\*(C'\fI\fR .IX Subsection "Furl::HTTP->new(%args | %args) :Furl" .PP Creates and returns a new Furl client with \fI\f(CI%args\fI\fR. Dies on errors. .PP \&\fI\f(CI%args\fI\fR might be: .ie n .IP "agent :Str = ""Furl/$VERSION""" 4 .el .IP "agent :Str = ``Furl/$VERSION''" 4 .IX Item "agent :Str = Furl/$VERSION" .PD 0 .IP "timeout :Int = 10" 4 .IX Item "timeout :Int = 10" .PD Seconds until the call to \f(CW$furl\fR\->request returns a timeout error (as an internally generated 500 error). The timeout might not be accurate since some underlying modules / built-ins function may block longer than the specified timeout. See the \*(L"\s-1FAQ\*(R"\s0 for how to support timeout during name resolution. .IP "inactivity_timeout :Int = 600" 4 .IX Item "inactivity_timeout :Int = 600" An inactivity timer for \s-1TCP\s0 read/write (in seconds). \f(CW$furl\fR\->request returns a timeout error if no additional data arrives (or is sent) within the specified threshold. .IP "max_redirects :Int = 7" 4 .IX Item "max_redirects :Int = 7" .PD 0 .IP "proxy :Str" 4 .IX Item "proxy :Str" .IP "no_proxy :Str" 4 .IX Item "no_proxy :Str" .IP "headers :ArrayRef" 4 .IX Item "headers :ArrayRef" .IP "header_format :Int = \s-1HEADERS_AS_ARRAYREF\s0" 4 .IX Item "header_format :Int = HEADERS_AS_ARRAYREF" .PD This option choose return value format of \f(CW\*(C`$furl\->request\*(C'\fR. .Sp This option allows \s-1HEADERS_NONE\s0 or \s-1HEADERS_AS_ARRAYREF.\s0 .Sp \&\fB\s-1HEADERS_AS_ARRAYREF\s0\fR is a default value. This makes \fB\f(CB$headers\fB\fR as ArrayRef. .Sp \&\fB\s-1HEADERS_NONE\s0\fR makes \fB\f(CB$headers\fB\fR as undef. Furl does not return parsing result of headers. You should take needed headers from \fBspecial_headers\fR. .IP "connection_pool :Object" 4 .IX Item "connection_pool :Object" This is the connection pool object for keep-alive requests. By default, it is a instance of Furl::ConnectionCache. .Sp You may not customize this variable otherwise to use Coro. This attribute requires a duck type object. It has two methods, \f(CW\*(C`$obj\->steal($host, $port\*(C'\fR and \f(CW\*(C`$obj\->push($host, $port, $sock)\*(C'\fR. .IP "stop_if :CodeRef" 4 .IX Item "stop_if :CodeRef" A callback function that is called by Furl after when a blocking function call returns \s-1EINTR.\s0 Furl will abort the \s-1HTTP\s0 request and return immediately if the callback returns true. Otherwise the operation is continued (the default behaviour). .IP "get_address :CodeRef" 4 .IX Item "get_address :CodeRef" A callback function to override the default address resolution logic. Takes three arguments: ($hostname, \f(CW$port\fR, \f(CW$timeout_in_seconds\fR) and returns: ($sockaddr, \f(CW$errReason\fR). If the returned \f(CW$sockaddr\fR is undef, then the resolution is considered as a failure and \f(CW$errReason\fR is propagated to the caller. .IP "inet_aton :CodeRef" 4 .IX Item "inet_aton :CodeRef" Deprecated. New applications should use \fBget_address\fR instead. .Sp A callback function to customize name resolution. Takes two arguments: ($hostname, \f(CW$timeout_in_seconds\fR). If omitted, Furl calls Socket::inet_aton. .IP "ssl_opts :HashRef" 4 .IX Item "ssl_opts :HashRef" \&\s-1SSL\s0 configuration used on https requests, passed directly to \f(CW\*(C`IO::Socket::SSL\->new()\*(C'\fR, .Sp for example: .Sp .Vb 1 \& use IO::Socket::SSL; \& \& my $ua = Furl::HTTP\->new( \& ssl_opts => { \& SSL_verify_mode => SSL_VERIFY_PEER(), \& }, \& }); .Ve .Sp See IO::Socket::SSL for details. .SS "Instance Methods" .IX Subsection "Instance Methods" \fI\f(CI\*(C`$furl\->request(%args) :($protocol_minor_version, $code, $msg, \e@headers, $body)\*(C'\fI\fR .IX Subsection "$furl->request(%args) :($protocol_minor_version, $code, $msg, @headers, $body)" .PP Sends an \s-1HTTP\s0 request to a specified \s-1URL\s0 and returns a protocol minor version, status code, status message, response headers, response body respectively. .PP \&\fI\f(CI%args\fI\fR might be: .ie n .IP "scheme :Str = ""http""" 4 .el .IP "scheme :Str = ``http''" 4 .IX Item "scheme :Str = http" Protocol scheme. May be \f(CW\*(C`http\*(C'\fR or \f(CW\*(C`https\*(C'\fR. .IP "host :Str" 4 .IX Item "host :Str" Server host to connect. .Sp You must specify at least \f(CW\*(C`host\*(C'\fR or \f(CW\*(C`url\*(C'\fR. .IP "port :Int = 80" 4 .IX Item "port :Int = 80" Server port to connect. The default is 80 on \f(CW\*(C`scheme => \*(Aqhttp\*(Aq\*(C'\fR, or 443 on \f(CW\*(C`scheme => \*(Aqhttps\*(Aq\*(C'\fR. .ie n .IP "path_query :Str = ""/""" 4 .el .IP "path_query :Str = ``/''" 4 .IX Item "path_query :Str = /" Path and query to request. .IP "url :Str" 4 .IX Item "url :Str" \&\s-1URL\s0 to request. .Sp You can use \f(CW\*(C`url\*(C'\fR instead of \f(CW\*(C`scheme\*(C'\fR, \f(CW\*(C`host\*(C'\fR, \f(CW\*(C`port\*(C'\fR and \f(CW\*(C`path_query\*(C'\fR. .IP "headers :ArrayRef" 4 .IX Item "headers :ArrayRef" \&\s-1HTTP\s0 request headers. e.g. \f(CW\*(C`headers => [ \*(AqAccept\-Encoding\*(Aq => \*(Aqgzip\*(Aq ]\*(C'\fR. .IP "content : Str | ArrayRef[Str] | HashRef[Str] | FileHandle" 4 .IX Item "content : Str | ArrayRef[Str] | HashRef[Str] | FileHandle" Content to request. .IP "write_file : FileHandle" 4 .IX Item "write_file : FileHandle" If this parameter is set, the response content will be saved here instead of in the response object. .Sp It's like a \f(CW\*(C`:content_file\*(C'\fR in LWP::UserAgent. .IP "write_code : CodeRef" 4 .IX Item "write_code : CodeRef" If a callback is provided with the \*(L"write_code\*(R" option then this function will be called for each chunk of the response content as it is received from the server. .Sp It's like a \f(CW\*(C`:content_cb\*(C'\fR in LWP::UserAgent. .PP The \f(CW\*(C`request()\*(C'\fR method assumes the first argument to be an instance of \f(CW\*(C`HTTP::Request\*(C'\fR if the arguments are an odd number: .PP .Vb 2 \& my $req = HTTP::Request\->new(...); \& my @res = $furl\->request($req); # allowed .Ve .PP You must encode all the queries or this method will die, saying \&\f(CW\*(C`Wide character in ...\*(C'\fR. .PP \fI\f(CI\*(C`$furl\->get($url :Str, $headers :ArrayRef[Str] )\*(C'\fI\fR .IX Subsection "$furl->get($url :Str, $headers :ArrayRef[Str] )" .PP This is an easy-to-use alias to \f(CW\*(C`request()\*(C'\fR, sending the \f(CW\*(C`GET\*(C'\fR method. .PP \fI\f(CI\*(C`$furl\->head($url :Str, $headers :ArrayRef[Str] )\*(C'\fI\fR .IX Subsection "$furl->head($url :Str, $headers :ArrayRef[Str] )" .PP This is an easy-to-use alias to \f(CW\*(C`request()\*(C'\fR, sending the \f(CW\*(C`HEAD\*(C'\fR method. .PP \fI\f(CI\*(C`$furl\->post($url :Str, $headers :ArrayRef[Str], $content :Any)\*(C'\fI\fR .IX Subsection "$furl->post($url :Str, $headers :ArrayRef[Str], $content :Any)" .PP This is an easy-to-use alias to \f(CW\*(C`request()\*(C'\fR, sending the \f(CW\*(C`POST\*(C'\fR method. .PP \fI\f(CI\*(C`$furl\->put($url :Str, $headers :ArrayRef[Str], $content :Any)\*(C'\fI\fR .IX Subsection "$furl->put($url :Str, $headers :ArrayRef[Str], $content :Any)" .PP This is an easy-to-use alias to \f(CW\*(C`request()\*(C'\fR, sending the \f(CW\*(C`PUT\*(C'\fR method. .PP \fI\f(CI\*(C`$furl\->delete($url :Str, $headers :ArrayRef[Str] )\*(C'\fI\fR .IX Subsection "$furl->delete($url :Str, $headers :ArrayRef[Str] )" .PP This is an easy-to-use alias to \f(CW\*(C`request()\*(C'\fR, sending the \f(CW\*(C`DELETE\*(C'\fR method. .SH "FAQ" .IX Header "FAQ" .IP "Why IO::Socket::SSL?" 4 .IX Item "Why IO::Socket::SSL?" Net::SSL is not well documented. .IP "Why is env_proxy optional?" 4 .IX 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. .IP "What operating systems are supported?" 4 .IX Item "What operating systems are supported?" Linux 2.6 or higher, \s-1OSX\s0 Tiger or higher, Windows \s-1XP\s0 or higher. .Sp And other operating systems will be supported if you send a patch. .IP "Why doesn't Furl support chunked upload?" 4 .IX Item "Why doesn't Furl support chunked upload?" There are reasons why chunked POST/PUTs should not be used in general. .Sp First, you cannot send chunked requests unless the peer server at the other end of the established \s-1TCP\s0 connection is known to be a \s-1HTTP/1.1\s0 server. .Sp Second, \s-1HTTP/1.1\s0 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. \s-1POST, PUT,\s0 etc.) as a succeeding request over persistent connections. .Sp These facts together makes using chunked requests virtually impossible (unless you _know_ that the server supports \s-1HTTP/1.1\s0), and this is why we decided that supporting the feature is \s-1NOT\s0 of high priority. .IP "How do you build the response content as it arrives?" 4 .IX Item "How do you build the response content as it arrives?" You can use IO::Callback for this purpose. .Sp .Vb 10 \& my $fh = IO::Callback\->new( \& \*(Aq<\*(Aq, \& sub { \& my $x = shift @data; \& $x ? "\-$x" : undef; \& } \& ); \& my ( $code, $msg, $headers, $content ) = \& $furl\->put( "http://127.0.0.1:$port/", [ \*(AqContent\-Length\*(Aq => $len ], $fh, \& ); .Ve .IP "How do you use gzip/deflate compressed communication?" 4 .IX Item "How do you use gzip/deflate compressed communication?" Add an \fBAccept-Encoding\fR header to your request. Furl inflates response bodies transparently according to the \fBContent-Encoding\fR response header. .IP "How do you use multipart/form\-data?" 4 .IX Item "How do you use multipart/form-data?" You can use multipart/form\-data with HTTP::Request::Common. .Sp .Vb 1 \& use HTTP::Request::Common; \& \& my $furl = Furl\->new(); \& $req = POST \*(Aqhttp://www.perl.org/survey.cgi\*(Aq, \& Content_Type => \*(Aqform\-data\*(Aq, \& Content => [ \& name => \*(AqHiromu Tokunaga\*(Aq, \& email => \*(Aqtokuhirom@example.com\*(Aq, \& gender => \*(AqF\*(Aq, \& born => \*(Aq1978\*(Aq, \& init => ["$ENV{HOME}/.profile"], \& ]; \& $furl\->request($req); .Ve .Sp Native multipart/form\-data support for Furl is available if you can send a patch for me. .IP "How do you use Keep-Alive and what happens on the \s-1HEAD\s0 method?" 4 .IX Item "How do you use Keep-Alive and what happens on the HEAD method?" Furl supports \s-1HTTP/1.1,\s0 hence \f(CW\*(C`Keep\-Alive\*(C'\fR. However, if you use the \s-1HEAD\s0 method, the connection is closed immediately. .Sp \&\s-1RFC 2616\s0 section 9.4 says: .Sp .Vb 2 \& The HEAD method is identical to GET except that the server MUST NOT \& return a message\-body in the response. .Ve .Sp Some web applications, however, returns message bodies on the \s-1HEAD\s0 method, which might confuse \f(CW\*(C`Keep\-Alive\*(C'\fR processes, so Furl closes connection in such cases. .Sp Anyway, the \s-1HEAD\s0 method is not so useful nowadays. The \s-1GET\s0 method and \&\f(CW\*(C`If\-Modified\-Since\*(C'\fR are more suitable to cache \s-1HTTP\s0 contents. .IP "Why does Furl take longer than specified until it returns a timeout error?" 4 .IX Item "Why does Furl take longer than specified until it returns a timeout error?" Although Furl itself supports timeout, some underlying modules / functions do not. And the most noticeable one is Socket::inet_aton, the function used for name resolution (a function that converts host names to \s-1IP\s0 addresses). If you need accurate and short timeout for name resolution, the use of Net::DNS::Lite is recommended. The following code snippet describes how to use the module in conjunction with Furl. .Sp .Vb 1 \& use Net::DNS::Lite qw(); \& \& my $furl = Furl\->new( \& timeout => $my_timeout_in_seconds, \& inet_aton => sub { Net::DNS::Lite::inet_aton(@_) }, \& ); .Ve .IP "How can I replace Host header instead of hostname?" 4 .IX Item "How can I replace Host header instead of hostname?" Furl::HTTP does not provide a way to replace the Host header because such a design leads to security issues. .Sp If you want to send \s-1HTTP\s0 requests to a dedicated server (or a \s-1UNIX\s0 socket), you should use the \fBget_address\fR callback to designate the peer to which Furl should connect as \fBsockaddr\fR. .Sp The example below sends all requests to 127.0.0.1:8080. .Sp .Vb 6 \& my $ua = Furl::HTTP\->new( \& get_address => sub { \& my ($host, $port, $timeout) = @_; \& pack_sockaddr_in(8080, inet_aton("127.0.0.1")); \& }, \& ); \& \& my ($minor_version, $code, $msg, $headers, $body) = $furl\->request( \& url => \*(Aqhttp://example.com/foo\*(Aq, \& method => \*(AqGET\*(Aq \& ); .Ve .SH "TODO" .IX Header "TODO" .Vb 3 \& \- AnyEvent::Furl? \& \- ipv6 support \& \- better docs for NO_PROXY .Ve .SH "OPTIONAL FEATURES" .IX Header "OPTIONAL FEATURES" .SS "Internationalized Domain Name (\s-1IDN\s0)" .IX Subsection "Internationalized Domain Name (IDN)" This feature requires Net::IDN::Encode. .SS "\s-1SSL\s0" .IX Subsection "SSL" This feature requires IO::Socket::SSL. .SS "Content-Encoding (deflate, gzip)" .IX Subsection "Content-Encoding (deflate, gzip)" This feature requires Compress::Raw::Zlib. .SH "DEVELOPMENT" .IX Header "DEVELOPMENT" To setup your environment: .PP .Vb 2 \& $ git clone http://github.com/tokuhirom/Furl.git \& $ cd Furl .Ve .PP To get picohttpparser: .PP .Vb 2 \& $ git submodule init \& $ git submodule update \& \& $ perl Makefile.PL \& $ make \& $ sudo make install .Ve .SS "\s-1HOW TO CONTRIBUTE\s0" .IX Subsection "HOW TO CONTRIBUTE" Please send the pull request via . .SH "SEE ALSO" .IX Header "SEE ALSO" \&\s-1LWP\s0 .PP \&\s-1HTTP\s0 specs: .SH "LICENSE" .IX Header "LICENSE" Copyright (C) Tokuhiro Matsuno. .PP This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.