Skip Menu |

This queue is for tickets about the Net-Async-HTTP CPAN distribution.

Report information
The Basics
Id: 102022
Status: resolved
Priority: 0/
Queue: Net-Async-HTTP

People
Owner: Nobody in particular
Requestors: WolfSage [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: (no value)
Fixed in: 0.39



Subject: do_request() - on_response still gets called with 4xx when fail_on_error => 1
Below, on_response() shouldn't be called since a 4xx is returned. I suspect this happens with 5xx as well. #!/usr/bin/env perl use strict; use warnings; use IO::Async::Loop; use Net::Async::HTTP; use URI; my $loop = IO::Async::Loop->new(); my $http = Net::Async::HTTP->new( fail_on_error => 1, ); $loop->add( $http ); $http->do_request( uri => URI->new( "http://www.cpan.org/asdfasdf" ), on_response => sub { print "Success: " . shift->as_string . "\n"; }, on_error => sub { print "Failure: " . shift . "\n" }, ); $loop->run; __END__ mhorsfall@tworivers:~$ ./http-ex.pl Success: HTTP/1.1 404 Not Found Connection: close Date: Mon, 09 Feb 2015 18:22:43 GMT Server: Apache/2.2.15 (Red Hat) Vary: Accept-Encoding Content-Length: 285 Content-Type: text/html; charset=iso-8859-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>404 Not Found</title> </head><body> <h1>Not Found</h1> <p>The requested URL /asdfasdf was not found on this server.</p> <hr> <address>Apache/2.2.15 (Red Hat) Server at www.cpan.org Port 80</address> </body></html> Failure: 404 Not Found
Patch attached. -- Paul Evans
Subject: rt102022.patch
=== modified file 'lib/Net/Async/HTTP.pm' --- lib/Net/Async/HTTP.pm 2015-07-13 10:33:41 +0000 +++ lib/Net/Async/HTTP.pm 2015-07-13 12:34:29 +0000 @@ -785,7 +785,7 @@ if( $args{on_header} ) { # ok } - elsif( my $on_response = delete $args{on_response} or defined wantarray ) { + elsif( $args{on_response} or defined wantarray ) { $args{on_header} = sub { my ( $response ) = @_; return sub { @@ -793,7 +793,6 @@ $response->add_content( @_ ); } else { - $on_response->( $response ) if $on_response; return $response; } }; @@ -827,6 +826,13 @@ $on_error->( $message, @rest ); }) if $on_error; + if( my $on_response = delete $args{on_response} ) { + $future->on_done( sub { + my ( $response ) = @_; + $on_response->( $response ); + }); + } + # DODGY HACK: # In void context we'll lose reference on the ->wait_any Future, so the # timeout logic will never happen. So lets purposely create a cycle by === modified file 't/04fail.t' --- t/04fail.t 2013-10-20 01:56:08 +0000 +++ t/04fail.t 2015-07-13 12:34:29 +0000 @@ -138,4 +138,46 @@ is( $response->code, 200, '$response->code for non-fail' ); } +# fail_on_error non-Future (RT102022) +{ + $http->configure( fail_on_error => 1 ); + + my $request = HTTP::Request->new( + GET => "/some/path", + [ Host => "myhost" ] + ); + + my ( $response_c, $request_c ); + $http->do_request( + method => "GET", + uri => URI->new( "http://host0/some/path" ), + on_response => sub { + die "Test failed - on_response with $_[0]"; + }, + on_error => sub { + ( my $message, $response_c, $request_c ) = @_; + is( $message, "404 Not Found", '$message to on_error' ); + }, + ); + + wait_for { $peersock }; + + # Wait for the client to send its request + my $request_stream = ""; + wait_for_stream { $request_stream =~ m/$CRLF$CRLF/ } $peersock => $request_stream; + + $peersock->syswrite( join( $CRLF, + "HTTP/1.1 404 Not Found", + "Content-Type: text/plain", + "Content-Length: 9", + "" ) . $CRLF . + "Not Found" + ); + + wait_for { defined $response_c }; + + is( $response_c->code, 404, '$response_c->code for fail_on_error true' ); + is( $request_c->uri, "http://host0/some/path", '$request_f->uri for fail_on_error true' ); +} + done_testing;
Was released in 0.39 -- Paul Evans