Skip Menu |
 

This queue is for tickets about the POE-Component-Client-HTTP CPAN distribution.

Report information
The Basics
Id: 14623
Status: resolved
Priority: 0/
Queue: POE-Component-Client-HTTP

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

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



Subject: PoCoCl::HTTP in some cases return double responses.
Download (untitled) / with headers
text/plain 542b
Some time ago I was saying that in some cases Cl::HTTP sends double responses (postbacks) to requesting session. Now I found this situation. That happens if remote host send RST TCP packet instead of FIN when closing connection (this behavior occur that socket has SO_LINGER turned on and linger time is 0). In this situation client receives correct response (because content-length bytes read successfully) and after it receives 400 response with error "read error 104: Connection reset by peer". I created a patch to fix this situation.
Index: HTTP.pm =================================================================== --- HTTP.pm (revision 217) +++ HTTP.pm (working copy) @@ -358,7 +358,9 @@ # If there was a non-zero error, then something bad happened. Post # an error response back. if ($errnum) { - $request->error(400, "$operation error $errnum: $errstr"); + unless ($request->[REQ_STATE] & RS_POSTED) { + $request->error(400, "$operation error $errnum: $errstr"); + } return; }
[YKAR - Fri Sep 16 17:31:49 2005]: Updated patch.
Download patch2.diff
text/x-diff 748b
Index: HTTP.pm =================================================================== --- HTTP.pm (revision 217) +++ HTTP.pm (working copy) @@ -247,6 +247,7 @@ # Post an error response back to the requesting session. $request->connect_error("$operation error $errnum: $errstr"); + $request->[REQ_STATE] |= RS_POSTED; } } @@ -358,7 +359,10 @@ # If there was a non-zero error, then something bad happened. Post # an error response back. if ($errnum) { - $request->error(400, "$operation error $errnum: $errstr"); + unless ($request->[REQ_STATE] & RS_POSTED) { + $request->error(400, "$operation error $errnum: $errstr"); + $request->[REQ_STATE] |= RS_POSTED; + } return; }
Download (untitled) / with headers
text/plain 912b
[YKAR - Sat Sep 17 03:27:32 2005]: Final patch and my comments. Found another case when two postbacks occures. If HTTP host return 302 code with headers and closes socket _brutally_ (with RST). Two postbacks are sent: 1. 500 Internal Server Error / Connection Reset By peer 2. Actual result after redirection So I updated the patch, I put error reporting code after (return if ($request->[REQ_STATE] == RS_REDIRECTED)). It is normal situation that host replied 302 Moved with complete headers and body and closed connection with RST. I don't feel any hesitation about this patch and I think that this patch is final for this problem. PS. I removed all $request->[REQ_STATE] |= REQ_POSTED which I added in previous patch (they are not needed because $request is deleted and alarm is removed) So this patch fix situation when connection closed with RST for any common response and for redirection response.
Index: HTTP.pm =================================================================== --- HTTP.pm (revision 217) +++ HTTP.pm (working copy) @@ -355,13 +355,6 @@ my $request = delete $heap->{request}->{$request_id}; $request->remove_timeout; - # If there was a non-zero error, then something bad happened. Post - # an error response back. - if ($errnum) { - $request->error(400, "$operation error $errnum: $errstr"); - return; - } - # Otherwise the remote end simply closed. If we've got a # pending response, then post it back to the client. DEBUG and warn "STATE is ", $request->[REQ_STATE]; @@ -369,6 +362,15 @@ # except when we're redirected return if ($request->[REQ_STATE] == RS_REDIRECTED); + # If there was a non-zero error, then something bad happened. Post + # an error response back. + if ($errnum) { + unless ($request->[REQ_STATE] & RS_POSTED) { + $request->error(400, "$operation error $errnum: $errstr"); + } + return; + } + if ( $request->[REQ_STATE] & (RS_IN_CONTENT | RS_DONE) and not $request->[REQ_STATE] & RS_POSTED
Download (untitled) / with headers
text/plain 134b
Applied. Thank you for the discussion of the problem and your patches. I don't think I would have understood the issue without them.


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

Please report any issues with rt.cpan.org to rt-cpan-admin@bestpractical.com.