Bug 38763 - mod_proxy does not handle asynchronous connection close correctly
Summary: mod_proxy does not handle asynchronous connection close correctly
Status: RESOLVED FIXED
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_proxy (show other bugs)
Version: 2.5-HEAD
Hardware: All All
: P2 regression (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords: RFC
Depends on:
Blocks:
 
Reported: 2006-02-23 10:51 UTC by Oliver Luik
Modified: 2008-12-26 10:59 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Oliver Luik 2006-02-23 10:51:28 UTC
We get sporadic "Bad Gateway" errors from mod_proxy.
In the error log we have entries like:
[Fri Feb 17 17:10:19 2006] [error] [client 192.168.55.72] proxy: error reading 
status line from remote server appsrv01i

We were able to track down the error to situation when the server 
asynchronously closes kept-alive connections and the client sent new requests.

According to http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html the 
following rules must be followed for persistent connections:
- A client, server, or proxy MAY close the transport connection at any
  time
- This means that clients, servers, and proxies MUST be able to recover
  from asynchronous close events.

Why are these rules not implemented in mod_proxy?
I do consider mod_proxy not to be HTTP keep-alive compliant in the current 
implementation.
Please comment.
Comment 1 Ruediger Pluem 2006-02-23 22:03:41 UTC
I admit that the current behaviour is not convenient, but I see no RFC violation
here. Please read the next two sentences in the RFC after

"This means that clients, servers, and proxies MUST be able to recover from
asynchronous close events."

The next two sentences say:

Client software SHOULD reopen the transport connection and retransmit the
aborted sequence of requests without user interaction so long as the request
sequence is idempotent (see section 9.1.2). Non-idempotent methods or sequences
MUST NOT be automatically retried, although user agents MAY offer a human
operator the choice of retrying the request(s).

The proxy can be seen as client in this case. 
1. There is no MUST for the client to retransmit if the request is idempotent.
2. If the request is not idempotent like POST it MUST NOT retransmit.
3. There is no definition what "recover" means. I see sending a Bad Gateway
response as some sort of recover from this situation.
Comment 2 Oliver Luik 2006-02-27 10:23:13 UTC
The current implementation with sending "Bad Gateway" response back to user 
agent (client) might be RFC compliant (hard to decide), but it is not the 
behaviour the user expects. For me a reverse proxy is not the client referred 
to in the RFC. The reverse proxy is a transparent intermediate that should only 
send own error messages back to the client in case of severe errors (ENOMEM, 
EINTERN,..).
IMO the best solution would be to delegate the async close back to the real 
client (browser). It already has to handle this situation when connected 
directly to the server. It is the only player in the game that can decide 
reliably what to do: retransmit, user interaction, etc

> Client software SHOULD reopen the transport connection and retransmit the
> aborted sequence of requests without user interaction so long as the request
> sequence is idempotent
According to RFC 2119 "SHOULD" is defined as:
SHOULD   This word, or the adjective "RECOMMENDED", mean that there
   may exist valid reasons in particular circumstances to ignore a
   particular item, but the full implications must be understood and
   carefully weighed before choosing a different course.


(In reply to comment #1)
> I admit that the current behaviour is not convenient, but I see no RFC 
violation
> here. Please read the next two sentences in the RFC after
> "This means that clients, servers, and proxies MUST be able to recover from
> asynchronous close events."
> The next two sentences say:
> Client software SHOULD reopen the transport connection and retransmit the
> aborted sequence of requests without user interaction so long as the request
> sequence is idempotent (see section 9.1.2). Non-idempotent methods or 
sequences
> MUST NOT be automatically retried, although user agents MAY offer a human
> operator the choice of retrying the request(s).
> The proxy can be seen as client in this case. 
> 1. There is no MUST for the client to retransmit if the request is idempotent.
> 2. If the request is not idempotent like POST it MUST NOT retransmit.
> 3. There is no definition what "recover" means. I see sending a Bad Gateway
> response as some sort of recover from this situation.

(In reply to comment #0)
> We get sporadic "Bad Gateway" errors from mod_proxy.
> In the error log we have entries like:
> [Fri Feb 17 17:10:19 2006] [error] [client 192.168.55.72] proxy: error 
reading 
> status line from remote server appsrv01i
> We were able to track down the error to situation when the server 
> asynchronously closes kept-alive connections and the client sent new requests.
> According to http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html the 
> following rules must be followed for persistent connections:
> - A client, server, or proxy MAY close the transport connection at any
>   time
> - This means that clients, servers, and proxies MUST be able to recover
>   from asynchronous close events.
> Why are these rules not implemented in mod_proxy?
> I do consider mod_proxy not to be HTTP keep-alive compliant in the current 
> implementation.
> Please comment.

(In reply to comment #1)
> I admit that the current behaviour is not convenient, but I see no RFC 
violation
> here. Please read the next two sentences in the RFC after
> "This means that clients, servers, and proxies MUST be able to recover from
> asynchronous close events."
> The next two sentences say:
> Client software SHOULD reopen the transport connection and retransmit the
> aborted sequence of requests without user interaction so long as the request
> sequence is idempotent (see section 9.1.2). Non-idempotent methods or 
sequences
> MUST NOT be automatically retried, although user agents MAY offer a human
> operator the choice of retrying the request(s).
> The proxy can be seen as client in this case. 
> 1. There is no MUST for the client to retransmit if the request is idempotent.
> 2. If the request is not idempotent like POST it MUST NOT retransmit.
> 3. There is no definition what "recover" means. I see sending a Bad Gateway
> response as some sort of recover from this situation.

Comment 3 Nick Kew 2007-09-08 06:33:08 UTC
(In reply to comment #0)

> We were able to track down the error to situation when the server 
> asynchronously closes kept-alive connections and the client sent new requests.

Can you clarify the exact sequence?

Is it something like:
  Proxy successfully handles Request 1
  Backend closes connection
  Client sends Request 2 to proxy
  Proxy tries to use existing connection, but it's closed at the backend
  Proxy replies with an error?

Or is it more asynchronous than that?
Comment 4 Nick Kew 2008-12-26 10:59:29 UTC
Handling of this case has been significantly updated; assuming fixed.  Please reopen if it persists in 2.2.11.