Giter Site home page Giter Site logo

furl's Introduction

NAME

Furl - Lightning-fast URL fetcher

SYNOPSIS

use Furl;

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

my $res = $furl->get('http://example.com/');
die $res->status_line unless $res->is_success;
print $res->content;

my $res = $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 Perl 5, but it is too slow for some critical jobs, and too complex for weekend hacking. Furl resolves these issues. Enjoy it!

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

  • capture_request :Bool = false

    If this parameter is true, Furl::HTTP captures raw request string. You can get it by $res->captured_req_headers and $res->captured_req_content.

  • proxy :Str

  • no_proxy :Str

  • headers :ArrayRef

  • cookie_jar :Object

    (EXPERIMENTAL)

    An instance of HTTP::CookieJar or equivalent class that supports the add and cookie_header methods

Instance Methods

$furl->request([$request,] %args) :Furl::Response

Sends an HTTP request to a specified URL and returns a instance of Furl::Response.

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

If the number of arguments is an odd number, this method assumes that the first argument is an instance of HTTP::Request. Remaining arguments can be any of the previously describe values (but currently there's no way to really utilize them, so don't use it)

my $req = HTTP::Request->new(...);
my $res = $furl->request($req);

You can also specify an object other than HTTP::Request (e.g. Furl::Request), but the object must implement the following methods:

  • uri
  • method
  • content
  • headers

These must return the same type of values as their counterparts in HTTP::Request.

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

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

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

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

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

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

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

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

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

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

    Note that Furl requires HTTP::Parser::XS, which seems an XS module but includes a pure Perl backend, HTTP::Parser::XS::PP.

  • I need more speed.

    See Furl::HTTP, which provides the low level interface of Furl. It is faster than Furl.pm since Furl::HTTP does not create response objects.

  • 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 = $f->request($req)->as_http_response;
      $res->request($req);
      $cookies->extract_cookies($res);
      # and use $res.
    
  • How do you limit the response content length?

    You can limit the content length by callback function.

      my $f = Furl->new();
      my $content = '';
      my $limit = 1_000_000;
      my %special_headers = ('content-length' => undef);
      my $res = $f->request(
          method          => 'GET',
          url             => $url,
          special_headers => \%special_headers,
          write_code      => sub {
              my ( $status, $msg, $headers, $buf ) = @_;
              if (($special_headers{'content-length'}||0) > $limit || length($content) > $limit) {
                  die "over limit: $limit";
              }
              $content .= $buf;
          }
      );
    
  • How do you display the progress bar?

      my $bar = Term::ProgressBar->new({count => 1024, ETA => 'linear'});
      $bar->minor(0);
      $bar->max_update_rate(1);
    
      my $f = Furl->new();
      my $content = '';
      my %special_headers = ('content-length' => undef);;
      my $did_set_target = 0;
      my $received_size = 0;
      my $next_update  = 0;
      $f->request(
          method          => 'GET',
          url             => $url,
          special_headers => \%special_headers,
          write_code      => sub {
              my ( $status, $msg, $headers, $buf ) = @_;
              unless ($did_set_target) {
                  if ( my $cl = $special_headers{'content-length'} ) {
                      $bar->target($cl);
                      $did_set_target++;
                  }
                  else {
                      $bar->target( $received_size + 2 * length($buf) );
                  }
              }
              $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 for details.

AUTHOR

Tokuhiro Matsuno [email protected]

Fuji, Goro (gfx)

THANKS TO

Kazuho Oku

mala

mattn

lestrrat

walf443

lestrrat

audreyt

SEE ALSO

LWP

IO::Socket::SSL

Furl::HTTP

Furl::Response

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.

furl's People

Contributors

audreyt avatar bayashi avatar bissei avatar ddeka2910 avatar debug-ito avatar eserte avatar garu avatar gfx avatar hirose31 avatar itchyny avatar kazeburo avatar kazuho avatar kimoto avatar ktat avatar lestrrat avatar masaki avatar mattn avatar neilb avatar plicease avatar s-aska avatar skaji avatar spiritloose avatar syohex avatar tarao avatar tokuhirom avatar walf443 avatar xaicron avatar yoshikazusawa avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

furl's Issues

Buggy keep-alive implementation

I find Furl's keep-alive implementation to cause problems.

I have an HTTP server that does implement keep-alive, but will close the connection after a period of idle time.

If I use Furl to make a request, then delay too long, then try again, Furl fails with "Connection reset by peer" error.

ie. This fails:

my $furl = Furl->new;
$furl->get($url);
sleep 120;
$furl->get($url);

but this succeeds:

Furl->new->get($url);
sleep 120;
Furl->new->get($url);

request_with_http_request

Hi!

In your cookie-usage example you use method 'request_with_http_request'. What you mean with this?

my $res = H$f->request_with_http_request($req)->as_http_response;

Certainly here is some typo (what 'H' before '$'), but I did not figure out the meaning here.

Wbr,

Gunnar

proxy経由SSLでのCONNECT後のheader部がcurlと異なっているため通信に失敗します

下記箇所を
https://github.com/tokuhirom/Furl/blob/master/lib/Furl/HTTP.pm#L368

my $request_uri = $proxy;

とすると、成功します。

curl --trace-asciiなどで確認したところ

  • curl
POST /path HTTP/1.1
User-Agent: curl/7.19.7 (universal-apple-darwin10.0) libcurl/7.1 9.7 OpenSSL/0.9.8x zlib/1.2.3
Host: overproxyhost
Accept: */*
Content-Length: 117
Content-Type: application/x-www-form-urlencoded
  • Furl
POST https://overproxyhost/path HTTP/1.1
User-Agent: Furl/2.19
Host: overproxyhost
Accept: */*
Content-Length: 117
Content-Type: application/x-www-form-urlencoded

と異なっていました。

プロキシ含めて、環境依存の可能性もあるかと思いましたが、curlと比較しても異なっていたので、issueとしました。

Declare Plack related modules in test_requires section.

Module fails to install if Plack is not installed on developer's server.

Also some modules are included in Makefile.PL, but rather should be declared in the 'build_requires' section, for example:

use Module::Install::AuthorTests;
use Module::Install::ReadmeMarkdownFromPod;

I also had no them installed on my developer's machine, and Furl installation failed.

Furl 3.12 - 3.14: t/100_low/38_continue.t seems to hang under Strawberry Perl 5.30.2 x64 (using cpan command)

Hello,

Similar to #73 and #118, but I report.

If I try to install Furl 3.12 - 3.14 using cpan command, It seems to me that t/100_low/38_continue.t hangs.
I downloaded Furl v3.14 from metacpan and tried to:

perl Build.PL
Build
prove -lv t/100_low/38_continue.t

All tests successful.

However, I continue to build test, t/100_low/38_continue.t seems to hang as follows.

C:\home\sunlight2\Furl-3.14>build test
t/00_compile.t .................................. 1/1 # Perl/v5.30.2
# Furl/3.14
# Net::IDN::Encode/2.5
# IO::Socket::SSL/2.067
# Compress::Raw::Zlib/2.096
t/00_compile.t .................................. ok
t/01_version.t .................................. ok
t/100_low/01_simple.t ........................... ok
t/100_low/03_redirect.t ......................... ok
t/100_low/04_chunked.t .......................... ok
t/100_low/05_slowloris.t ........................ ok
t/100_low/06_errors.t ........................... ok
t/100_low/07_timeout.t .......................... ok
t/100_low/08_proxy.t ............................ skipped: Test requires module 'HTTP::Proxy' but it's not found
t/100_low/09_body.t ............................. ok
t/100_low/11_write_file.t ....................... ok
t/100_low/12_write_code.t ....................... ok
t/100_low/13_deflate.t .......................... ok
t/100_low/15_multiline_header.t ................. ok
t/100_low/16_read_callback.t .................... ok
t/100_low/17_keep_alive.t ....................... 1/? # cannot read HTTP request header: 既存の接続はリモート ホストに強制的に切断されました。 at C:/home/sunlight2/Furl-3.14/t/100_low/../../t/HTTPServer.pm line 136.
t/100_low/17_keep_alive.t ....................... ok
t/100_low/18_no_proxy.t ......................... skipped: Test requires module 'HTTP::Proxy' but it's not found
t/100_low/19_special_headers.t .................. ok
t/100_low/20_header_format_none.t ............... ok
t/100_low/21_keep_alive_timedout.t .............. ok
t/100_low/22_keep_alive.t ....................... skipped: Test requires module 'Starlet::Server' but it's not found
t/100_low/22_keep_alive_http10.t ................ skipped: Test requires module 'Starlet' but it's not found
t/100_low/23_redirect_relative.t ................ ok
t/100_low/24_no_content.t ....................... ok
t/100_low/25_signal.t ........................... skipped: Win32 is not supported
t/100_low/26_headers_only.t ..................... received a broken HTTP request at t/100_low/26_headers_only.t line 58.t/100_low/26_headers_only.t ..................... ok
t/100_low/27_close_on_eof.t ..................... ok
t/100_low/28_idn.t .............................. ok
t/100_low/29_completion_slash.t ................. ok
t/100_low/30_user_agent.t ....................... ok
t/100_low/31_chunked_unexpected_eof.t ........... ok
t/100_low/32_proxy_auth.t ....................... skipped: Test requires module 'HTTP::Proxy::HeaderFilter::simple' but
it's not found
t/100_low/33_basic_auth.t ....................... ok
t/100_low/34_keep_request.t ..................... ok
t/100_low/35_get_address.t ...................... ok
t/100_low/36_inactivity_timeout.t ............... 1/? # took 2 seconds
# took 0 seconds
t/100_low/36_inactivity_timeout.t ............... ok
t/100_low/37_bad_content_length.t ............... Use of uninitialized value $_ in concatenation (.) or string at t/100_low/37_bad_content_length.t line 35.
t/100_low/37_bad_content_length.t ............... ok
t/100_low/38_continue.t ......................... 1/?

[Environment]
Windows 8.1 x64
Strawberry Perl 5.30.2 x64

Class::Accessor::Lite 0.08
Encode 3.09
HTTP::Parser::XS 0.17
MIME::Base64 3.16
Mozilla::CA 20200520
Scalar::Util 1.56
Socket 2.031
Time::HiRes 1.9764_02

File::Temp 0.2311
Test::More 1.302183
Test::Requires 0.10
Test::TCP 2.22

Module::Build::Tiny 0.039

Thank you,

Timeout aborts response in progress

If I try to download a large file the timeout kicks in even though the response is currently being received. This doesn't seem like the right way for a timeout to work. I think the sanest fix might be to reset the timeout every time a chunk is received or maybe have two separate timeouts, one for the whole request and one for the wait between each chunk being sent.

IDN resolution may raise an exception

https://github.com/tokuhirom/p5-Furl/blob/master/lib/Furl/HTTP.pm#L247

When you resolve hostnames via IDN, this method may throw an exception.
.... Which would be OK, except since it's Furl, I fully expected this to work:

my (undef, $code) = $furl->get( "http://some-host-that-needs-IDN-resolution" );
if ( ! HTTP::Status::is_success($code) ) {
     warn "Error!";
     return;
}

But since IDN raises an exception, we need to do

my (undef, $code) = eval { $furl->get( "http://some-host-that-needs-IDN-resolution" ) };
if ( $@ || ! HTTP::Status::is_success($code) ) {
     warn "Error!";
     return;
}

Perhaps the call to IDN resolution should be wrapped in an eval, and an appropriate 500 response should be returned?

内部からアクセスすると504 Gateway Time-outする

初めまして。
Nginx+fcgiwrapにて、ブラウザよりアクセスするプログラムを書いているのですが、
運用するhogehoge.com の内部から、同じhogehoge.com内にあるAPIを叩こうとするとTimeoutになります。

my $url = 'https://hogehoge.com/api/getData';
my $f = Furl->new();
my $res = $f->get($url);
print Dumper($res);

$VAR1 = bless( { 'captured_req_content' => undef, 'headers' => bless( { 'x-internal-response' => [ 1 ], 'content-length' => [ 87 ] }, 'Furl::Headers' ), 'content' => 'Cannot read response header: timeout at *********.cgi line 18. ', 'request_src' => { 'headers' => undef, 'url' => 'https://hogehoge.com/api/getData', 'method' => 'GET' }, 'message' => 'Internal Response: Cannot read response header: timeout at *******.cgi line 18. ', 'captured_req_headers' => undef, 'minor_version' => 0, 'code' => 500 }, 'Furl::Response' );

**urlを外のもの(例えば https://jlp.yahooapis.jp/~ みたい)にすると問題なくGETできます。
これは仕様なのでしょうか。それとも何か見落としがあるのでしょうか。
初心者的質問で申し訳ありませんが、ヒントを頂ければ助かります。

install issue

[956]$ perl Makefile.PL 
include /private/tmp/p5-Furl/inc/Module/Install.pm
include inc/Module/Install/Metadata.pm
include inc/Module/Install/Base.pm
include inc/Module/Install/ReadmeMarkdownFromPod.pm
include inc/Module/Install/Makefile.pm
Cannot determine perl version info from lib/Furl.pm
Cannot find an extension with method 'readme_from' at /opt/local/lib/perl5/site_perl/5.12.2/Module/Install/Admin.pm line 186.

Test freezing during install

Freeze at t\100_low\29_completion_slash.t for more than 15 mins, after this was interrupted by ctrl+c.

Environment:
MSWin 8.1 x64
Strawberry perl 5.20.0 x64

Log:

d:\projects\pcore>cpanm Furl -v
cpanm (App::cpanminus) 1.7004 on perl 5.020000 built for MSWin32-x64-multi-thread
Work directory is d:\tmp\.cpanm/work/1402487430.6296
You have make D:\devel\dmake\dmake.exe
You have LWP 6.06
You have D:\devel\git\bin\tar.exe, D:\devel\git\bin\gzip.exe and D:\devel\git\bin\bzip2.exe
You have D:\devel\git\bin\unzip.exe
Searching Furl on cpanmetadb ...
--> Working on Furl
Fetching http://www.cpan.org/authors/id/T/TO/TOKUHIROM/Furl-3.02.tar.gz ... OK
Unpacking Furl-3.02.tar.gz
Furl-3.02/Build.PL
Furl-3.02/Changes
Furl-3.02/LICENSE
Furl-3.02/META.json
Furl-3.02/README.md
Furl-3.02/TODO
Furl-3.02/author/benchmark/byown.pl
Furl-3.02/author/benchmark/note.mkdn
Furl-3.02/author/benchmark/profile.pl
Furl-3.02/author/benchmark/simple.pl
Furl-3.02/author/mk-chunked-response.pl
Furl-3.02/cpanfile
Furl-3.02/example/get.pl
Furl-3.02/lib/Furl.pm
Furl-3.02/lib/Furl/ConnectionCache.pm
Furl-3.02/lib/Furl/HTTP.pm
Furl-3.02/lib/Furl/Headers.pm
Furl-3.02/lib/Furl/Request.pm
Furl-3.02/lib/Furl/Response.pm
Furl-3.02/lib/Furl/ZlibStream.pm
Furl-3.02/t/00_compile.t
Furl-3.02/t/01_version.t
Furl-3.02/t/100_low/01_simple.t
Furl-3.02/t/100_low/03_redirect.t
Furl-3.02/t/100_low/04_chunked.t
Furl-3.02/t/100_low/05_slowloris.t
Furl-3.02/t/100_low/06_errors.t
Furl-3.02/t/100_low/07_timeout.t
Furl-3.02/t/100_low/08_proxy.t
Furl-3.02/t/100_low/09_body.t
Furl-3.02/t/100_low/11_write_file.t
Furl-3.02/t/100_low/12_write_code.t
Furl-3.02/t/100_low/13_deflate.t
Furl-3.02/t/100_low/15_multiline_header.t
Furl-3.02/t/100_low/16_read_callback.t
Furl-3.02/t/100_low/17_keep_alive.t
Furl-3.02/t/100_low/18_no_proxy.t
Furl-3.02/t/100_low/19_special_headers.t
Furl-3.02/t/100_low/20_header_format_none.t
Furl-3.02/t/100_low/21_keep_alive_timedout.t
Furl-3.02/t/100_low/22_keep_alive_http10.t
Furl-3.02/t/100_low/23_redirect_relative.t
Furl-3.02/t/100_low/24_no_content.t
Furl-3.02/t/100_low/25_signal.t
Furl-3.02/t/100_low/26_headers_only.t
Furl-3.02/t/100_low/27_close_on_eof.t
Furl-3.02/t/100_low/28_idn.t
Furl-3.02/t/100_low/29_completion_slash.t
Furl-3.02/t/100_low/30_user_agent.t
Furl-3.02/t/100_low/31_chunked_unexpected_eof.t
Furl-3.02/t/100_low/32_proxy_auth.t
Furl-3.02/t/100_low/33_basic_auth.t
Furl-3.02/t/100_low/34_keep_request.t
Furl-3.02/t/100_low/35_get_address.t
Furl-3.02/t/100_low/36_inactivity_timeout.t
Furl-3.02/t/300_high/01_simple.t
Furl-3.02/t/300_high/02_agent.t
Furl-3.02/t/300_high/04_http_request.t
Furl-3.02/t/300_high/05_suppress_dup_host_header.t
Furl-3.02/t/300_high/06_keep_request.t
Furl-3.02/t/300_high/07_cookie.t
Furl-3.02/t/300_high/99_error.t
Furl-3.02/t/400_components/001_response-coding/01-file.t
Furl-3.02/t/400_components/001_response-coding/t-euc-jp.html
Furl-3.02/t/400_components/001_response-coding/t-iso-2022-jp.html
Furl-3.02/t/400_components/001_response-coding/t-null.html
Furl-3.02/t/400_components/001_response-coding/t-shiftjis.html
Furl-3.02/t/400_components/001_response-coding/t-utf-8.html
Furl-3.02/t/400_components/01_headers.t
Furl-3.02/t/400_components/02_response.t
Furl-3.02/t/400_components/03_request.t
Furl-3.02/t/800_regression/01_capture_request.t
Furl-3.02/t/999_intrenal/parse_url.t
Furl-3.02/t/HTTPServer.pm
Furl-3.02/t/Slowloris.pm
Furl-3.02/t/Util.pm
Furl-3.02/xt/02_perlcritic.t
Furl-3.02/xt/04_leaktrace.t
Furl-3.02/xt/05_valgrind.t
Furl-3.02/xt/200_online/01_idn.t
Furl-3.02/xt/200_online/02_google.t
Furl-3.02/xt/200_online/03_yahoo_com.t
Furl-3.02/xt/200_online/04_ssl.t
Furl-3.02/xt/200_online/05_connect_error.t
Furl-3.02/xt/200_online/06_net-dns-lite.t
Furl-3.02/xt/200_online/07_ssl_shutdown.t
Furl-3.02/xt/perlcriticrc
Furl-3.02/META.yml
Furl-3.02/MANIFEST
Entering Furl-3.02
Checking configure dependencies from META.json
Checking if you have Module::Build 0.38 ... Yes (0.4205)
Checking if you have CPAN::Meta 0 ... Yes (2.141520)
Checking if you have CPAN::Meta::Prereqs 0 ... Yes (2.141520)
Checking if you have Module::Build 0.36 ... Yes (0.4205)
Running Build.PL
Configuring Furl-3.02 ... Created MYMETA.yml and MYMETA.json
Creating new 'Build' script for 'Furl' version '3.02'
Merging cpanfile prereqs to MYMETA.yml
Merging cpanfile prereqs to MYMETA.json
OK
Checking dependencies from MYMETA.json ...
Checking if you have Test::Requires 0 ... Yes (0.07)
Checking if you have Mozilla::CA 0 ... Yes (20130114)
Checking if you have Class::Accessor::Lite 0 ... Yes (0.06)
Checking if you have Time::HiRes 0 ... Yes (1.9726)
Checking if you have File::Temp 0 ... Yes (0.2304)
Checking if you have Test::More 0.96 ... Yes (1.001003)
Checking if you have Socket 0 ... Yes (2.014)
Checking if you have MIME::Base64 0 ... Yes (3.14)
Checking if you have HTTP::Parser::XS 0.11 ... Yes (0.16)
Checking if you have ExtUtils::CBuilder 0 ... Yes (0.280216)
Checking if you have Encode 0 ... Yes (2.62)
Checking if you have Scalar::Util 0 ... Yes (1.39)
Checking if you have Test::TCP 1.06 ... Yes (2.02)
Building and testing Furl-3.02 ... Building Furl
t\00_compile.t .................................. 1/1 # Perl/v5.20.0
# Furl/3.02
# Net::IDN::Encode/(not installed)
# IO::Socket::SSL/1.992
# Compress::Raw::Zlib/2.065
t\00_compile.t .................................. ok
t\01_version.t .................................. ok
t\100_low\01_simple.t ........................... ok
t\100_low\03_redirect.t ......................... ok
t\100_low\04_chunked.t .......................... ok
t\100_low\05_slowloris.t ........................ ok
t\100_low\06_errors.t ........................... ok
t\100_low\07_timeout.t .......................... ok
t\100_low\08_proxy.t ............................ skipped: Test requires module 'HTTP::Proxy' but it's not found
t\100_low\09_body.t ............................. ok
t\100_low\11_write_file.t ....................... ok
t\100_low\12_write_code.t ....................... ok
t\100_low\13_deflate.t .......................... skipped: Test requires module 'Plack::Middleware::Deflater' but it's not found
t\100_low\15_multiline_header.t ................. ok
t\100_low\16_read_callback.t .................... skipped: Test requires module 'IO::Callback' but it's not found
t\100_low\17_keep_alive.t ....................... ok
t\100_low\18_no_proxy.t ......................... skipped: Test requires module 'HTTP::Proxy' but it's not found
t\100_low\19_special_headers.t .................. ok
t\100_low\20_header_format_none.t ............... ok
t\100_low\21_keep_alive_timedout.t .............. ok
t\100_low\22_keep_alive_http10.t ................ skipped: Test requires module 'Starlet' but it's not found
t\100_low\23_redirect_relative.t ................ ok
t\100_low\24_no_content.t ....................... ok
t\100_low\25_signal.t ........................... skipped: Win32 is not supported
t\100_low\26_headers_only.t ..................... received a broken HTTP request at t\100_low\26_headers_only.t line 53.
t\100_low\26_headers_only.t ..................... ok
t\100_low\27_close_on_eof.t ..................... ok
t\100_low\28_idn.t .............................. skipped: Test requires module 'Net::IDN::Encode' but it's not found
t\100_low\29_completion_slash.t ................. 10/?

Can't call method "is_success" on unblessed reference

Code:

use strict;
use Furl;
my $furl = Furl::HTTP->new(
    agent   => '',
    timeout => 3,
);
my $res = $furl->get('https://en.wikipedia.org/');
die $res->status_line unless $res->is_success;
print $res->content;

Error:

Can't call method "is_success" on unblessed reference

Timeout is not occurred in 100_low/07_timeout.t on recent Linux kernel

Furl tests are failed on Linux kernel version 3.8
while tests are passed on Linux kernel version 3.5.

Because expected timeout is not occurred on Linux 3.8.

Log is below.

% uname -rv
3.8.0-21-generic #32-Ubuntu SMP Tue May 14 22:16:46 UTC 2013x86_64 x86_64
% prove -bv t/100_low/07_timeout.t                                                                                                                           (master)[~/tmp/gomi/Furl]
t/100_low/07_timeout.t .. 
# read_timeout
ok 1 - request()/1
ok 2
ok 3
ok 4 - content: Cannot read response header: timeout at t/100_low/07_timeout.t line 25.
# 
ok 5
ok 6 - request()/2
ok 7
ok 8
ok 9 - content: Cannot read response header: timeout at t/100_low/07_timeout.t line 25.
# 
ok 10
# write_timeout
ok 11 - request()/1
not ok 12

#   Failed test at t/100_low/07_timeout.t line 58.
#                   'Internal Response: Cannot read response header: timeout at t/100_low/07_timeout.t line 49.
# '
#     doesn't match '(?^:Internal Response: Failed to send content: timeout)'
ok 13
ok 14
ok 15 - content: Cannot read response header: timeout at t/100_low/07_timeout.t line 49.
# 
ok 16
ok 17 - request()/2
not ok 18

#   Failed test at t/100_low/07_timeout.t line 58.
#                   'Internal Response: Cannot read response header: timeout at t/100_low/07_timeout.t line 49.
# '
#     doesn't match '(?^:Internal Response: Failed to send content: timeout)'
ok 19
ok 20
ok 21 - content: Cannot read response header: timeout at t/100_low/07_timeout.t line 49.
# 
ok 22
1..22
# Looks like you failed 2 tests of 22.
Dubious, test returned 2 (wstat 512, 0x200)
Failed 2/22 subtests 

Test Summary Report
-------------------
t/100_low/07_timeout.t (Wstat: 512 Tests: 22 Failed: 2)
  Failed tests:  12, 18
  Non-zero exit status: 2
Files=1, Tests=22,  4 wallclock secs ( 0.02 usr  0.00 sys +  0.10 cusr  0.02 csys =  0.14 CPU)
Result: FAIL

Timeout is occurred and tests are passed if size of input data is doubled.
(SO_SNDBUF on Linux 3.8 is 16KB same as Linux 3.5.)

diff --git a/t/100_low/07_timeout.t b/t/100_low/07_timeout.t
index 4af9768..83d0a2c 100644
--- a/t/100_low/07_timeout.t
+++ b/t/100_low/07_timeout.t
@@ -48,7 +48,7 @@ test_tcp(
                     path_query => '/foo',
                     content    => do {
                         # should be larger than SO_SNDBUF (we use 1MB)
-                        my $content = "0123456789abcdef" x 64 x 1024;
+                        my $content = "0123456789abcdef" x 64 x 2048;
                         open my $fh, '<', \$content or die "oops";
                         $fh;
                     },

I think that input data of timeout test should be bigger.

"Keep-Alive" is no effect

In line 526 of Furl/HTTP.pm, FURL checks the HTTP response headers it gets from the server. It will read the Connection from the response header there, and compare the header value with the string keep-alive. The problem is that this does not take into account a different case of the response header. Some HTTP server returns a header value of Keep-Alive (mind the caps), so FURL does not recognize it properly.

I think the following change to Furl/HTTP.pm is more robust.

  • if ($connection_header eq 'keep-alive') {
  • if (lc($connection_header) eq 'keep-alive') {

Furl leaks DNS requests when SOCKS proxy is used

First of all I want to say that I'm not sure if this is an issue in Furl or if it's just lack of proper configuration.
I'm using Furl on a project of mine and would like to add support for SOCKS proxy. This is simple to do. Something like the following works fine:

use strict;
use IO::Socket::Socks::Wrapper (
    {
            ProxyAddr => '127.0.0.1',
            ProxyPort => 9050,
            SocksDebug => 1,
            Timeout => 15,
    },
);
use Furl;
my $furl = Furl->new(
    timeout => 10,
);
my ($minor_version, $code, $msg, $headers, $body) = $furl->request(
    method     => 'GET',
    host       => 'target.host.com',
    port       => 80,
    path_query => '/'
);

However, I noticed that currently the Furl module still leaks the DNS requests outside of the Socks proxy connection which I'm trying to avoid.
Have you ever done this in the past or do you have any suggestions on how to implement this? I suppose it would be something regarding the get_address callback or maybe wrapping the right classes in the Socks wrapper... but I haven't figured it out.

To test this, one can use a service like "https://canarytokens.org/generate#" to generate a DNS token and then use the generated hostname as the Furl's host parameter. Run the code and then observe that the report sent to the email contains the IP address of your normal DNS server instead of the tunneled one via SOCKS. To quickly setup a SOCKS proxy you can just use TOR which listens in 127.0.0.1:9050 by default.

support relative url in redirection

18:09 kazuho____: !~ m{^[a-z0-9]+://} じゃなかったら URI ロードして解決とかなんですかねー
18:09 kazuho____: やらないけどw
18:09 kazuho____: Location: http:../hoge とかはさすがにみたことないなー
18:10 tokuhirom: うひ
18:10 tokuhirom: URI.pm つかっちゃうのが楽ですなー
18:10 nyarla-net has left IRC (Quit: Leaving...)
18:11 clouder is now known as clou_zzz
18:11 kazuho____: ほとんどのケースで URI.pm が不要なら、ちょっとくらい false-positive がでて URL.pm での解決になっちゃってもいいだろうし

Furl: tests fail on Perl 5 blead; no dot in default @INC

In Perl 5.26.0 -- coming out within the next two months -- . will no longer be found by default in @INC. That means that Perl programs -- such as the tests in t/*.t -- which do not provide for . in @INC will fail.

Today I built Perl 5 blead and then installed cpanm against that perl. I then attempted to configure, build and test Furl against that perl. These were my results.

$ ./Build test
t/00_compile.t .................................. 1/1 # Perl/v5.26.0
# Furl/3.09
# Net::IDN::Encode/2.4
# IO::Socket::SSL/2.047
# Compress::Raw::Zlib/2.074
t/00_compile.t .................................. ok   
t/01_version.t .................................. ok   
t/100_low/01_simple.t ........................... Can't locate t/HTTPServer.pm in @INC (you may need to install the t::HTTPServer module) (@INC contains: /home/jkeenan/gitwork/zzzothers/Furl/blib/arch /home/jkeenan/gitwork/zzzothers/Furl/blib/lib /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0 /home/jkeenan/testing/blead/lib/perl5/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/5.26.0) at t/100_low/01_simple.t line 6.
BEGIN failed--compilation aborted at t/100_low/01_simple.t line 6.
t/100_low/01_simple.t ........................... Dubious, test returned 2 (wstat 512, 0x200)
No subtests run 
t/100_low/03_redirect.t ......................... ok   
t/100_low/04_chunked.t .......................... Can't locate t/HTTPServer.pm in @INC (you may need to install the t::HTTPServer module) (@INC contains: /home/jkeenan/gitwork/zzzothers/Furl/blib/arch /home/jkeenan/gitwork/zzzothers/Furl/blib/lib /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0 /home/jkeenan/testing/blead/lib/perl5/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/5.26.0) at t/100_low/04_chunked.t line 6.
BEGIN failed--compilation aborted at t/100_low/04_chunked.t line 6.
t/100_low/04_chunked.t .......................... Dubious, test returned 2 (wstat 512, 0x200)
No subtests run 
t/100_low/05_slowloris.t ........................ Can't locate t/Slowloris.pm in @INC (you may need to install the t::Slowloris module) (@INC contains: /home/jkeenan/gitwork/zzzothers/Furl/blib/arch /home/jkeenan/gitwork/zzzothers/Furl/blib/lib /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0 /home/jkeenan/testing/blead/lib/perl5/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/5.26.0) at t/100_low/05_slowloris.t line 10.
BEGIN failed--compilation aborted at t/100_low/05_slowloris.t line 10.
t/100_low/05_slowloris.t ........................ Dubious, test returned 2 (wstat 512, 0x200)
No subtests run 
t/100_low/06_errors.t ........................... ok    
t/100_low/07_timeout.t .......................... Can't locate t/Slowloris.pm in @INC (you may need to install the t::Slowloris module) (@INC contains: /home/jkeenan/gitwork/zzzothers/Furl/blib/arch /home/jkeenan/gitwork/zzzothers/Furl/blib/lib /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0 /home/jkeenan/testing/blead/lib/perl5/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/5.26.0) at t/100_low/07_timeout.t line 10.
BEGIN failed--compilation aborted at t/100_low/07_timeout.t line 10.
t/100_low/07_timeout.t .......................... Dubious, test returned 2 (wstat 512, 0x200)
No subtests run 
t/100_low/08_proxy.t ............................ skipped: Test requires module 'HTTP::Proxy' but it's not found
t/100_low/09_body.t ............................. ok    
t/100_low/11_write_file.t ....................... ok   
t/100_low/12_write_code.t ....................... ok   
t/100_low/13_deflate.t .......................... Can't locate t/Slowloris.pm in @INC (you may need to install the t::Slowloris module) (@INC contains: /home/jkeenan/gitwork/zzzothers/Furl/blib/arch /home/jkeenan/gitwork/zzzothers/Furl/blib/lib /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0 /home/jkeenan/testing/blead/lib/perl5/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/5.26.0) at t/100_low/13_deflate.t line 13.
BEGIN failed--compilation aborted at t/100_low/13_deflate.t line 13.
t/100_low/13_deflate.t .......................... Dubious, test returned 2 (wstat 512, 0x200)
No subtests run 
t/100_low/15_multiline_header.t ................. ok   
t/100_low/16_read_callback.t .................... skipped: Test requires module 'IO::Callback' but it's not found
t/100_low/17_keep_alive.t ....................... Can't locate t/HTTPServer.pm in @INC (you may need to install the t::HTTPServer module) (@INC contains: /home/jkeenan/gitwork/zzzothers/Furl/blib/arch /home/jkeenan/gitwork/zzzothers/Furl/blib/lib /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0 /home/jkeenan/testing/blead/lib/perl5/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/5.26.0) at t/100_low/17_keep_alive.t line 6.
BEGIN failed--compilation aborted at t/100_low/17_keep_alive.t line 6.
t/100_low/17_keep_alive.t ....................... Dubious, test returned 2 (wstat 512, 0x200)
No subtests run 
t/100_low/18_no_proxy.t ......................... skipped: Test requires module 'HTTP::Proxy' but it's not found
t/100_low/19_special_headers.t .................. ok    
t/100_low/20_header_format_none.t ............... ok    
t/100_low/21_keep_alive_timedout.t .............. Can't locate t/HTTPServer.pm in @INC (you may need to install the t::HTTPServer module) (@INC contains: /home/jkeenan/gitwork/zzzothers/Furl/blib/arch /home/jkeenan/gitwork/zzzothers/Furl/blib/lib /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0 /home/jkeenan/testing/blead/lib/perl5/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/5.26.0) at t/100_low/21_keep_alive_timedout.t line 7.
BEGIN failed--compilation aborted at t/100_low/21_keep_alive_timedout.t line 7.
t/100_low/21_keep_alive_timedout.t .............. Dubious, test returned 2 (wstat 512, 0x200)
No subtests run 
t/100_low/22_keep_alive_http10.t ................ skipped: Test requires module 'Starlet' but it's not found
t/100_low/23_redirect_relative.t ................ ok   
t/100_low/24_no_content.t ....................... Can't locate t/HTTPServer.pm in @INC (you may need to install the t::HTTPServer module) (@INC contains: /home/jkeenan/gitwork/zzzothers/Furl/blib/arch /home/jkeenan/gitwork/zzzothers/Furl/blib/lib /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0 /home/jkeenan/testing/blead/lib/perl5/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/5.26.0) at t/100_low/24_no_content.t line 6.
BEGIN failed--compilation aborted at t/100_low/24_no_content.t line 6.
t/100_low/24_no_content.t ....................... Dubious, test returned 2 (wstat 512, 0x200)
No subtests run 
t/100_low/25_signal.t ........................... Can't locate t/HTTPServer.pm in @INC (you may need to install the t::HTTPServer module) (@INC contains: /home/jkeenan/gitwork/zzzothers/Furl/blib/arch /home/jkeenan/gitwork/zzzothers/Furl/blib/lib /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0 /home/jkeenan/testing/blead/lib/perl5/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/5.26.0) at t/100_low/25_signal.t line 7.
BEGIN failed--compilation aborted at t/100_low/25_signal.t line 7.
t/100_low/25_signal.t ........................... Dubious, test returned 2 (wstat 512, 0x200)
No subtests run 
t/100_low/26_headers_only.t ..................... received a broken HTTP request at t/100_low/26_headers_only.t line 58.
t/100_low/26_headers_only.t ..................... ok    
t/100_low/27_close_on_eof.t ..................... ok   
t/100_low/28_idn.t .............................. Can't locate t/HTTPServer.pm in @INC (you may need to install the t::HTTPServer module) (@INC contains: /home/jkeenan/gitwork/zzzothers/Furl/blib/arch /home/jkeenan/gitwork/zzzothers/Furl/blib/lib /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0 /home/jkeenan/testing/blead/lib/perl5/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/5.26.0) at t/100_low/28_idn.t line 5.
BEGIN failed--compilation aborted at t/100_low/28_idn.t line 5.
t/100_low/28_idn.t .............................. Dubious, test returned 2 (wstat 512, 0x200)
No subtests run 
t/100_low/29_completion_slash.t ................. Can't locate t/HTTPServer.pm in @INC (you may need to install the t::HTTPServer module) (@INC contains: /home/jkeenan/gitwork/zzzothers/Furl/blib/arch /home/jkeenan/gitwork/zzzothers/Furl/blib/lib /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0 /home/jkeenan/testing/blead/lib/perl5/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/5.26.0) at t/100_low/29_completion_slash.t line 6.
BEGIN failed--compilation aborted at t/100_low/29_completion_slash.t line 6.
t/100_low/29_completion_slash.t ................. Dubious, test returned 2 (wstat 512, 0x200)
No subtests run 
t/100_low/30_user_agent.t ....................... Can't locate t/HTTPServer.pm in @INC (you may need to install the t::HTTPServer module) (@INC contains: /home/jkeenan/gitwork/zzzothers/Furl/blib/arch /home/jkeenan/gitwork/zzzothers/Furl/blib/lib /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0 /home/jkeenan/testing/blead/lib/perl5/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/5.26.0) at t/100_low/30_user_agent.t line 6.
BEGIN failed--compilation aborted at t/100_low/30_user_agent.t line 6.
t/100_low/30_user_agent.t ....................... Dubious, test returned 2 (wstat 512, 0x200)
No subtests run 
t/100_low/31_chunked_unexpected_eof.t ........... ok   
t/100_low/32_proxy_auth.t ....................... skipped: Test requires module 'HTTP::Proxy::HeaderFilter::simple' but it's not found
t/100_low/33_basic_auth.t ....................... Can't locate t/HTTPServer.pm in @INC (you may need to install the t::HTTPServer module) (@INC contains: /home/jkeenan/gitwork/zzzothers/Furl/blib/arch /home/jkeenan/gitwork/zzzothers/Furl/blib/lib /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0 /home/jkeenan/testing/blead/lib/perl5/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/5.26.0) at t/100_low/33_basic_auth.t line 6.
BEGIN failed--compilation aborted at t/100_low/33_basic_auth.t line 6.
t/100_low/33_basic_auth.t ....................... Dubious, test returned 2 (wstat 512, 0x200)
No subtests run 
t/100_low/34_keep_request.t ..................... Can't locate t/HTTPServer.pm in @INC (you may need to install the t::HTTPServer module) (@INC contains: /home/jkeenan/gitwork/zzzothers/Furl/blib/arch /home/jkeenan/gitwork/zzzothers/Furl/blib/lib /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0 /home/jkeenan/testing/blead/lib/perl5/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/5.26.0) at t/100_low/34_keep_request.t line 7.
BEGIN failed--compilation aborted at t/100_low/34_keep_request.t line 7.
t/100_low/34_keep_request.t ..................... Dubious, test returned 2 (wstat 512, 0x200)
No subtests run 
t/100_low/35_get_address.t ...................... Can't locate t/HTTPServer.pm in @INC (you may need to install the t::HTTPServer module) (@INC contains: /home/jkeenan/gitwork/zzzothers/Furl/blib/arch /home/jkeenan/gitwork/zzzothers/Furl/blib/lib /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0 /home/jkeenan/testing/blead/lib/perl5/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/5.26.0) at t/100_low/35_get_address.t line 8.
BEGIN failed--compilation aborted at t/100_low/35_get_address.t line 8.
t/100_low/35_get_address.t ...................... Dubious, test returned 2 (wstat 512, 0x200)
No subtests run 
t/100_low/36_inactivity_timeout.t ............... Can't locate t/Slowloris.pm in @INC (you may need to install the t::Slowloris module) (@INC contains: /home/jkeenan/gitwork/zzzothers/Furl/blib/arch /home/jkeenan/gitwork/zzzothers/Furl/blib/lib /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0 /home/jkeenan/testing/blead/lib/perl5/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/5.26.0) at t/100_low/36_inactivity_timeout.t line 9.
BEGIN failed--compilation aborted at t/100_low/36_inactivity_timeout.t line 9.
t/100_low/36_inactivity_timeout.t ............... Dubious, test returned 2 (wstat 512, 0x200)
No subtests run 
t/100_low/37_bad_content_length.t ............... Can't locate t/HTTPServer.pm in @INC (you may need to install the t::HTTPServer module) (@INC contains: /home/jkeenan/gitwork/zzzothers/Furl/blib/arch /home/jkeenan/gitwork/zzzothers/Furl/blib/lib /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0 /home/jkeenan/testing/blead/lib/perl5/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/5.26.0) at t/100_low/37_bad_content_length.t line 7.
BEGIN failed--compilation aborted at t/100_low/37_bad_content_length.t line 7.
t/100_low/37_bad_content_length.t ............... Dubious, test returned 2 (wstat 512, 0x200)
No subtests run 
t/100_low/38_continue.t ......................... Can't locate t/HTTPServer.pm in @INC (you may need to install the t::HTTPServer module) (@INC contains: /home/jkeenan/gitwork/zzzothers/Furl/blib/arch /home/jkeenan/gitwork/zzzothers/Furl/blib/lib /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0 /home/jkeenan/testing/blead/lib/perl5/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/5.26.0) at t/100_low/38_continue.t line 7.
BEGIN failed--compilation aborted at t/100_low/38_continue.t line 7.
t/100_low/38_continue.t ......................... Dubious, test returned 2 (wstat 512, 0x200)
No subtests run 
t/100_low/39_httpoxy.t .......................... ok   
t/300_high/01_simple.t .......................... ok    
t/300_high/02_agent.t ........................... ok   
t/300_high/04_http_request.t .................... ok   
t/300_high/05_suppress_dup_host_header.t ........ Can't locate t/HTTPServer.pm in @INC (you may need to install the t::HTTPServer module) (@INC contains: /home/jkeenan/gitwork/zzzothers/Furl/blib/arch /home/jkeenan/gitwork/zzzothers/Furl/blib/lib /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/site_perl/5.26.0 /home/jkeenan/testing/blead/lib/perl5/5.26.0/x86_64-linux /home/jkeenan/testing/blead/lib/perl5/5.26.0) at t/300_high/05_suppress_dup_host_header.t line 7.
BEGIN failed--compilation aborted at t/300_high/05_suppress_dup_host_header.t line 7.
t/300_high/05_suppress_dup_host_header.t ........ Dubious, test returned 2 (wstat 512, 0x200)
No subtests run 
t/300_high/06_keep_request.t .................... ok    
t/300_high/07_cookie.t .......................... ok   
t/300_high/99_error.t ........................... ok   
t/400_components/001_response-coding/01-file.t .. ok     
t/400_components/01_headers.t ................... ok   
t/400_components/02_response.t .................. ok    
t/400_components/03_request.t ................... ok   
t/800_regression/01_capture_request.t ........... ok   
t/999_intrenal/parse_url.t ...................... ok    

Test Summary Report
-------------------
t/100_low/01_simple.t                         (Wstat: 512 Tests: 0 Failed: 0)
  Non-zero exit status: 2
  Parse errors: No plan found in TAP output
t/100_low/04_chunked.t                        (Wstat: 512 Tests: 0 Failed: 0)
  Non-zero exit status: 2
  Parse errors: No plan found in TAP output
t/100_low/05_slowloris.t                      (Wstat: 512 Tests: 0 Failed: 0)
  Non-zero exit status: 2
  Parse errors: No plan found in TAP output
t/100_low/07_timeout.t                        (Wstat: 512 Tests: 0 Failed: 0)
  Non-zero exit status: 2
  Parse errors: No plan found in TAP output
t/100_low/13_deflate.t                        (Wstat: 512 Tests: 0 Failed: 0)
  Non-zero exit status: 2
  Parse errors: No plan found in TAP output
t/100_low/17_keep_alive.t                     (Wstat: 512 Tests: 0 Failed: 0)
  Non-zero exit status: 2
  Parse errors: No plan found in TAP output
t/100_low/21_keep_alive_timedout.t            (Wstat: 512 Tests: 0 Failed: 0)
  Non-zero exit status: 2
  Parse errors: No plan found in TAP output
t/100_low/24_no_content.t                     (Wstat: 512 Tests: 0 Failed: 0)
  Non-zero exit status: 2
  Parse errors: No plan found in TAP output
t/100_low/25_signal.t                         (Wstat: 512 Tests: 0 Failed: 0)
  Non-zero exit status: 2
  Parse errors: No plan found in TAP output
t/100_low/28_idn.t                            (Wstat: 512 Tests: 0 Failed: 0)
  Non-zero exit status: 2
  Parse errors: No plan found in TAP output
t/100_low/29_completion_slash.t               (Wstat: 512 Tests: 0 Failed: 0)
  Non-zero exit status: 2
  Parse errors: No plan found in TAP output
t/100_low/30_user_agent.t                     (Wstat: 512 Tests: 0 Failed: 0)
  Non-zero exit status: 2
  Parse errors: No plan found in TAP output
t/100_low/33_basic_auth.t                     (Wstat: 512 Tests: 0 Failed: 0)
  Non-zero exit status: 2
  Parse errors: No plan found in TAP output
t/100_low/34_keep_request.t                   (Wstat: 512 Tests: 0 Failed: 0)
  Non-zero exit status: 2
  Parse errors: No plan found in TAP output
t/100_low/35_get_address.t                    (Wstat: 512 Tests: 0 Failed: 0)
  Non-zero exit status: 2
  Parse errors: No plan found in TAP output
t/100_low/36_inactivity_timeout.t             (Wstat: 512 Tests: 0 Failed: 0)
  Non-zero exit status: 2
  Parse errors: No plan found in TAP output
t/100_low/37_bad_content_length.t             (Wstat: 512 Tests: 0 Failed: 0)
  Non-zero exit status: 2
  Parse errors: No plan found in TAP output
t/100_low/38_continue.t                       (Wstat: 512 Tests: 0 Failed: 0)
  Non-zero exit status: 2
  Parse errors: No plan found in TAP output
t/300_high/05_suppress_dup_host_header.t      (Wstat: 512 Tests: 0 Failed: 0)
  Non-zero exit status: 2
  Parse errors: No plan found in TAP output
Files=51, Tests=350, 12 wallclock secs ( 0.13 usr  0.07 sys +  4.28 cusr  0.39 csys =  4.87 CPU)
Result: FAIL

t/800_regression/01_capture_request.t fails in presence of wildcard DNS records

Furl's test suite fails on many of my smokers like this:

#   Failed test at t/800_regression/01_capture_request.t line 10.
#          got: 'POST / HTTP/1.1
# Connection: keep-alive
# User-Agent: Furl::HTTP/3.14
# Host: example.com.local
# 
# '
#     expected: undef

#   Failed test at t/800_regression/01_capture_request.t line 11.
#          got: ''
#     expected: undef
# Looks like you failed 2 tests of 2.
t/800_regression/01_capture_request.t ........... 
Dubious, test returned 2 (wstat 512, 0x200)
Failed 2/2 subtests 

The problem is that the test hostname example.com.local, which obviously should not exist, actually resolves to something which has a web server running. This seems to happen if
a) the local DNS configuration does a fallback search for one or more domains (usually the default is to search for the local domain)
b) one of these domains has a wildcard DNS record
c) a webserver is running on the resolved address

It can be reproduced using the following Dockerfile (by experiments I found out that bing.com has a wildcard DNS record):

# docker build -t perl-test . && docker run -rm perl-test
FROM debian:11
RUN apt-get -y update
RUN apt-get -y --no-install-recommends install perl make cpanminus
RUN apt-get -y --no-install-recommends install libclass-accessor-lite-perl libencode-perl libhttp-parser-xs-perl
RUN apt-get -y --no-install-recommends install libtest-tcp-perl
ENV LOCALDOMAIN bing.com
CMD cpanm --test-only --verbose Furl

How can this be resolved? The LOCALDOMAIN environment variable is possibly Linux-specific, but setting it's value to something really non-existent might help on these systems. Additionally maybe do a gethostbyname call and check if it really returns nothing, otherwise skip the test.

support 204 No Cotnent

20:16 ikebe: https://gist.github.com/723347 これでいいんだっけ。
20:17 ikebe: test のレイアウトがよく分からんかった。。
20:18 ikebe: All 1xx (informational), 204 (no content), and 304 (not modified) responses MUST NOT include a message-body. だそうなので、

POST request times out in Win32 when posting a file with CR,LF line terminator.

In Windows, when doing a POST request a file with CR,LF newlines, the request times out. I tried to trace down the problem and what I have found so far is that when the Content-Length is calculated, the file size is calculated correctly. On the other hand, the number of bytes received by the server equals the Content-Length minus the number of lines in the file, that's why the server times out waiting for the total of bytes to be transferred.

I'm not expert in how the PerlIO layers work, but the documentation mentions that in MS-DOS like systems a translation from CR,LF into \n is made, so that's seems to be the reason why the server is reading one byte short per each line of the file. If I change the file handle to binmode before my request, the problem is fixed.

This is where the questions arise: Is it responsability of the user to set the file handle to binmode? Or should this be transparent to the user?

I noticed the problem when the test t\100_low\09_body.t failed because the file was transformed to CRLF terminators when I cloned from github. If the file has the Unix terminator, the test is successful.

Thanks

lwp compatible layer

there's already an LWP::Curl, how about an LWP::Furl? then all we need is an LWP::Any OR Any::LWP.

Specifying LocalAddr/bind IP for outgoing requests

Hello,

I have tried using get_address, LocalAddr, and inet_aton to no avail in my attempts to set the outbound IP/local bind address. Looking over https://github.com/tokuhirom/Furl/blob/master/lib/Furl/HTTP.pm it seems as though IO::Socket can be used similar to https://github.com/tokuhirom/Furl/blob/master/lib/Furl/HTTP.pm#L1355 however I'm fairly sure I'm doing it wrong. For example, I tried doing the following:

my $furl = Furl->new(
inet_aton => sub { new IO::Socket::INET( LocalAddr => $ips[rand @ips]); },
ssl_opts => { SSL_verify_mode => '0' },
timeout => '30',
inactivity_timeout => '30',
max_redirects => '0',
headers => [ 'Accept-Encoding' => 'gzip', 'Connection' => 'close' ]
);
Which resulted in error:

Thread 20 terminated abnormally: Bad arg length for Socket::pack_sockaddr_in, length is 37, should be 4 at /usr/local/share/perl5/Furl/HTTP.pm line 676.

Does anyone have a working example for setting the outbound IP address, or perhaps a patch?

Option to disable Mozilla::CA

IO::Socket::SSL will take the OpenSSL default CA store as the store for the trusted CA. This usually works on UNIX systems. [1] So it makes sense to rely on the default CA store on such systems.

For the openSUSE package I have therefore patched out the use of Mozilla::CA. I tested this change for both cases (certificate accepted and certificate rejected) and it works.

It would be nice if a configuration option to disable that code block would be provided by upstream.


The documentation of IO::Socket::SSL also claims that if there are no certificates in the store it will try use Mozilla::CA which provides the default CAs of Firefox. [1] So removing the code paths requiring Mozilla::CA completely as my patch does should not even make a difference if one wants that fallback. However, I haven't tested that in an environment where OpenSSL's default store is empty.


[1] https://metacpan.org/pod/IO::Socket::SSL#Basic-SSL-Client

Debugging possibilities with Furl?

Now the internet is more and more using https, traditional debugging tools like strace or tcpdump cannot be used anymore to debug problems in the https communication.
For LWP there's thankfully LWP::ConsoleLogger::Everywhere and LWP::Protocol::Net::Curl, which can be used to intercept and display http/https communication. And this is even possible without adapting the debugged script.

I wonder if there's something similar for Furl?

Returning 500 status code when no connection is made.

Just spent way to much time debugging an issue with Furl, that I'd like you to consider patching (and documenting) so that others don't get caught.

Upgraded from OpenSSL 1.0.2 -> 1.1.1 and unfortunately something went wrong and the CA file did not get updated, so was getting a response code of '500' from Furl - which was uncaught and confusing to say the least - it was only when I dumped the response I saw this:

             'content' => 'Cannot create SSL connection: SSL connect attempt failed error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed at <script> line 189.',

and realised part of the problem.. I had spent many hours trying to work out what was wrong in the server end looking for 500 errors as it was talking to a development site running mod_perl2...

Respectfully may I request that rather than a 500 error in the response code, return something less 'web server sane' like 'undef' or 999 or 000 etc .. just so that anyone getting the code would instantly know 'this didn't come from the remote server' and look deeper. (Second issue I ran into was IO::Socket::SSL also failed to upgrade and setting SSL_version=>'TLSv1_3' also crashed it out.. not really your problem, but similar issue.) I personally would probably return undef or -1 to a response code in the event of the connection to a remote server failing altogether, but that's me.

Regards,

Michelle

capture_requestをtrueにしているけどYou can't call cpatured_req_headers method without 'capture_request' options for Furl#newといわれる

はじめまして。

以下のワンライナーでタイトルのような不具合にであいましてどうしたものかなと。

$ perl -w -MFurl -E 'my $f=Furl->new(capture_request=>1, timeout=>5);my $r=$f->post("http://example.com.local");say $r->captured_req_headers'
You can't call cpatured_req_headers method without 'capture_request' options for Furl#new at -e line 1.

存在しないURLというか、Handshakeできなかった場合にも
postからはFurl::Responseが返ってくるけどcaptured_req_headersは呼べないので
どうやって受け側でハンドリングするのがよいかなと思っています。
環境はMacでperlは5.18.0になります。

よろしくお願いします。

Has Error at during the installation

Furl must have dependency with ExtUtils::Config, ExtUtils::InstallPaths and ExtUtils::Helpers at during the installation.
So, I have failed 3 times for installing like cpanm Furl -v on my Mac.

is there no test?

if there isn’t, I will try to fix it.

"Cannot resolve host name" but it's alive

https://bank.teraren.com/ is an alive site, so we can visit it.

but with using Furl,

$ perl -MFurl -e 'print Furl->new->get("https://bank.teraren.com/")->content'
Cannot resolve host name: bank.teraren.com (port: 443),  at -e line 1.

And I wonder why, getting JSON has succeeded like below:

$ perl -MFurl -e 'print Furl->new->get("https://bank.teraren.com/banks/0001.json")->content'
{"code":"0001","kana":"ミズホ","name":"みずほ","created_at":"2018-05-31T11:20:39.000Z","updated_at":"2018-05-31T11:20:39.000Z"}%

Is it the matter of DNS or this module or my settings?

  • I DID upgrade cpan modules with cpan-outdated | cpanm
  • the DNS record of this domain was updated on 06/21/2018
  • I found this issue on 06/21/2018

If it was not caused by Furl, the first code I wrote above is a mystery.

Recurring cyg32 failures from perl 5.20.1 to 5.16.2 Furl 3.07

Hi,
on a 32-bit cygwin on w7-x64 as in

% stephan@armen (/xddxc) %
% uname -a; cygcheck -dc | grep -i -e ^cygwin' ' -e ^gcc-core
CYGWIN_NT-6.1-WOW armen 1.7.35(0.287/5/3) 2015-03-04 12:07 i686 Cygwin
Cygwin Package Information
cygwin 1.7.35-1
gcc-core 4.9.2-3

I get the following.
Note that the same failures occur on 5.20.0, 5.16.3 and 5.16.2
I observe a big difference in the nunber of tests run between 5.20.1 and 5.20.1

hth cheers --stephan

for 5.20.1 cutting off the OKs
...
t/100_low/21_keep_alive_timedout.t .............. 1/?

Failed test 'request()/2'
at t/100_low/21_keep_alive_timedout.t line 23.
got: '500'
expected: '200'

Failed test at t/100_low/21_keep_alive_timedout.t line 24.
got: 'Internal Response: Cannot read response header: Software caused connection abort at t/100_low/21_keep_alive_timedout.t line 17.
'
expected: 'OK'

Failed test 'header'
at t/100_low/21_keep_alive_timedout.t line 25.
got: '109'
expected: '2'
[
'Content-Length',
109,
'X-Internal-Response',
1
]

Failed test at t/100_low/21_keep_alive_timedout.t line 27.
got: undef
expected: 'keep-alive'

Failed test at t/100_low/21_keep_alive_timedout.t line 29.
got: 'Cannot read response header: Software caused connection abort at t/100_low/21_keep_alive_timedout.t line 17.
'
expected: 'OK'
SV = PV(0x8002bc78) at 0x80070ae0
REFCNT = 1
FLAGS = (PADMY,POK,IsCOW,pPOK)
PV = 0x805823d8 "Cannot read response header: Software caused connection abort at t/100_low/21_keep_alive_timedout.t line 17.\n"\0
CUR = 109
LEN = 136
COW_REFCNT = 1
t/100_low/21_keep_alive_timedout.t .............. 11/? # Looks like you failed 5 tests of 15.
t/100_low/21_keep_alive_timedout.t .............. Dubious, test returned 5 (wstat 1280, 0x500)
Failed 5/15 subtests

Test Summary Report

t/100_low/21_keep_alive_timedout.t (Wstat: 1280 Tests: 15 Failed: 5)
Failed tests: 6-10
Non-zero exit status: 5
Files=49, Tests=811, 196 wallclock secs ( 0.83 usr 0.78 sys + 21.38 cusr 53.62 csys = 76.61 CPU)
Result: FAIL
Failed 1/49 test programs. 5/811 subtests failed.
FAIL
! Installing Furl failed. See /home/stephan/.cpanm/work/1429616126.14044/build.log for details. Retry with --force to force install it.

+++ ignoring /p20b/cpanmu

+++ ignoring /p63b/cpanmu

+++ ignoring /p62b/cpanmu

for 5.20.0 note the diff in tests run. Could be due to mods not installed...

Test Summary Report

t/100_low/21_keep_alive_timedout.t (Wstat: 1280 Tests: 15 Failed: 5)
Failed tests: 6-10
Non-zero exit status: 5
Files=49, Tests=898, 218 wallclock secs ( 0.83 usr 1.19 sys + 22.29 cusr 60.76 csys = 85.06 CPU)
Result: FAIL
Failed 1/49 test programs. 5/898 subtests failed.
FAIL
! Installing Furl failed. See /home/stephan/.cpanm/work/1429616133.6548/build.log for details. Retry with --force to force install it.

SSL_verify_mode should be configurable

Newer IO::Socket::SSL claims SSL_verify_mode like as:

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

So Furl should provide a way to configure SSL options.

This problem occurred on using App::dropboxapi.

Hangs During Install Windows 10

Hi,
Review all the previous issues (similar to #73) and not been able to fix. Can you please assist

Perl Dist: Strawberry
Perl Version: This is perl 5, version 30, subversion 0 (v5.30.0) built for MSWin32-x64-multi-thread

Install View:
C:\XMLTV>cpan Furl
Loading internal logger. Log::Log4perl recommended for better logging
CPAN: CPAN::SQLite loaded ok (v0.217)
Database was generated on Sat, 10 Aug 2019 23:28:28 GMT
Running install for module 'Furl'
CPAN: Digest::SHA loaded ok (v6.02)
CPAN: Compress::Zlib loaded ok (v2.086)
Checksum for C:\STRAWB~1\cpan\sources\authors\id\T\TO\TOKUHIROM\Furl-3.13.tar.gz ok
CPAN: Archive::Tar loaded ok (v2.32)
CPAN: YAML::XS loaded ok (v0.78)
CPAN: CPAN::Meta::Requirements loaded ok (v2.140)
CPAN: Parse::CPAN::Meta loaded ok (v2.150010)
CPAN: CPAN::Meta loaded ok (v2.150010)
CPAN: Module::Build loaded ok (v0.4229)
CPAN: Module::CoreList loaded ok (v5.20190522)
Configuring T/TO/TOKUHIROM/Furl-3.13.tar.gz with Build.PL
Creating new 'Build' script for 'Furl' version '3.13'
TOKUHIROM/Furl-3.13.tar.gz
C:\Strawberry\perl\bin\perl.exe Build.PL -- OK
Running Build for T/TO/TOKUHIROM/Furl-3.13.tar.gz
cp lib/Furl/ConnectionCache.pm blib\lib\Furl\ConnectionCache.pm
cp lib/Furl/Response.pm blib\lib\Furl\Response.pm
cp lib/Furl/ZlibStream.pm blib\lib\Furl\ZlibStream.pm
cp lib/Furl/HTTP.pm blib\lib\Furl\HTTP.pm
cp lib/Furl/Request.pm blib\lib\Furl\Request.pm
cp lib/Furl/Headers.pm blib\lib\Furl\Headers.pm
cp lib/Furl.pm blib\lib\Furl.pm
TOKUHIROM/Furl-3.13.tar.gz
C:\Strawberry\perl\bin\perl.exe ./Build -- OK
Running Build test for TOKUHIROM/Furl-3.13.tar.gz
t/00_compile.t .................................. 1/1 # Perl/v5.30.0

Furl/3.13

Net::IDN::Encode/2.5

IO::Socket::SSL/2.066

Compress::Raw::Zlib/2.086

t/00_compile.t .................................. ok
t/01_version.t .................................. ok
t/100_low/01_simple.t ........................... 1/?

-----Then it hangs and need to ^C to exit.

t/100_low/01_simple.t ........................... 1/? Terminating on signal SIGINT(2)
Terminating on signal SIGINT(2)
Terminating on signal SIGINT(2)
Terminate batch job (Y/N)?

Log:

distribution: !!perl/hash:CPAN::Distribution
CALLED_FOR: Furl::HTTP
CHECKSUM_STATUS: OK
CONTAINSMODS:
Furl: 1
Furl::ConnectionCache: 1
Furl::HTTP: 1
Furl::Headers: 1
Furl::Request: 1
Furl::Response: 1
Furl::ZlibStream: 1
ID: T/TO/TOKUHIROM/Furl-3.13.tar.gz
RO:
CPAN_USERID: TOKUHIROM
CPAN_VERSION: '3.13'
DESCRIPTION: ~
archived: tar
build_dir: C:\STRAWB1\cpan\build\Furl-3.13-0
incommandcolor: 1
localfile: C:\STRAWB
1\cpan\sources\authors\id\T\TO\TOKUHIROM\Furl-3.13.tar.gz
make: !!perl/hash:CPAN::Distrostatus
COMMANDID: 0
FAILED: ''
TEXT: YES
TIME: 1565488094
mandatory: 1
modulebuild: 1
negative_prefs_cache: 0
prefs: {}
prereq_pm:
build_requires:
File::Temp: '0'
Test::More: '0.96'
Test::Requires: '0'
Test::TCP: '2.11'
opt_build_requires: {}
opt_requires:
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'
perl: '5.008001'
reqtype: c
unwrapped: !!perl/hash:CPAN::Distrostatus
COMMANDID: 0
FAILED: ''
TEXT: YES
TIME: 1565488079
writemakefile: !!perl/hash:CPAN::Distrostatus
COMMANDID: 0
FAILED: ''
TEXT: YES
TIME: 1565488082
perl:
$^X: C:\Strawberry\perl\bin\perl.exe
mtime_$^X: 1558578486
mtime_dll: 0
sitearchexp: C:\STRAWB~1\perl\site\lib
time: 1565488094


Any help appreciated.

Load IO::Socket::SSL before start timeout counter.

Loading IO::Socket::SSL takes 0.05+ seconds.

[tokuhirom@dev2 Furl]$ perl -e 'use Time::HiRes qw/gettimeofday tv_interval/; $s=[gettimeofday]; require("IO/Socket/SSL.pm"); die tv_interval($s)'
0.060706 at -e line 1.
[tokuhirom@dev2 Furl]$ perl -e 'use Time::HiRes qw/gettimeofday tv_interval/; $s=[gettimeofday]; require("IO/Socket/SSL.pm"); die tv_interval($s)'
0.064392 at -e line 1.
[tokuhirom@dev2 Furl]$ perl -e 'use Time::HiRes qw/gettimeofday tv_interval/; $s=[gettimeofday]; require("IO/Socket/SSL.pm"); die tv_interval($s)'
0.089703 at -e line 1.
[tokuhirom@dev2 Furl]$ perl -e 'use Time::HiRes qw/gettimeofday tv_interval/; $s=[gettimeofday]; require("IO/Socket/SSL.pm"); die tv_interval($s)'
0.088434 at -e line 1.
[tokuhirom@dev2 Furl]$ perl -e 'use Time::HiRes qw/gettimeofday tv_interval/; $s=[gettimeofday]; require("IO/Socket/SSL.pm"); die tv_interval($s)'
0.06396 at -e line 1.
[tokuhirom@dev2 Furl]$ perl -e 'use Time::HiRes qw/gettimeofday tv_interval/; $s=[gettimeofday]; require("IO/Socket/SSL.pm"); die tv_interval($s)'
0.132832 at -e line 1.
[tokuhirom@dev2 Furl]$ perl -e 'use Time::HiRes qw/gettimeofday tv_interval/; $s=[gettimeofday]; require("IO/Socket/SSL.pm"); die tv_interval($s)'
0.061254 at -e line 1.
[tokuhirom@dev2 Furl]$ perl -e 'use Time::HiRes qw/gettimeofday tv_interval/; $s=[gettimeofday]; require("IO/Socket/SSL.pm"); die tv_interval($s)'
0.060395 at -e line 1.

In the current implementation, Furl includes IO::Socket::SSL's loading time as a timeout secs.
As a result, when a user sets short timeout seconds, Furl timeouts at the first time.

Suggestion

Do not include library loading time in timeout seconds .

How to use Furl with cookies?

Hello!
How to use Furl with cookies? In docs:

my $f = Furl->new();
my $cookies = HTTP::Cookies->new();
my $req = HTTP::Request->new(...);
$cookies->add_cookie_header($req);

What to write here?

my $res = H$f->request_with_http_request($req)->as_http_response;

$res->request($req);
$cookies->extract_cookies($res);

and use $res.

800_regression/01_capture_request.t Failing for Me

This is an odd one. Any thoughts?

#   Failed test at t/800_regression/01_capture_request.t line 10.
#          got: 'POST / HTTP/1.1
# Connection: keep-alive
# User-Agent: Furl::HTTP/3.05
# Host: www.mycompany.com
# 
# '
#     expected: undef

#   Failed test at t/800_regression/01_capture_request.t line 11.
#          got: ''
#     expected: undef
# Looks like you failed 2 tests of 2.
t/800_regression/01_capture_request.t ........... 
Dubious, test returned 2 (wstat 512, 0x200)
Failed 2/2 subtests 

bug while request.

Argument "318,318" isn't numeric in numeric ne (!=) at /usr/local/share/perl/5.14.2/Furl/HTTP.pm line 787.
Version of module 3.03

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.