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.
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.
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.
(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?
Handling of this case has been significantly updated; assuming fixed. Please reopen if it persists in 2.2.11.