- From: Zhong Yu <zhong.j.yu@gmail.com>
- Date: Wed, 4 Jun 2014 18:24:19 -0500
- To: Willy Tarreau <w@1wt.eu>
- Cc: Michael Sweet <msweet@apple.com>, "William Chan (?????????)" <willchan@chromium.org>, HTTP Working Group <ietf-http-wg@w3.org>, Matt Menke <mmenke@chromium.org>
On Wed, Jun 4, 2014 at 4:55 PM, Willy Tarreau <w@1wt.eu> wrote: > On Wed, Jun 04, 2014 at 03:45:55PM -0500, Zhong Yu wrote: >> On Wed, Jun 4, 2014 at 1:46 PM, Willy Tarreau <w@1wt.eu> wrote: >> > On Wed, Jun 04, 2014 at 11:15:30AM -0500, Zhong Yu wrote: >> >> On Wed, Jun 4, 2014 at 10:28 AM, Willy Tarreau <w@1wt.eu> wrote: >> >> > On Wed, Jun 04, 2014 at 10:22:48AM -0500, Zhong Yu wrote: >> >> >> On Wed, Jun 4, 2014 at 7:49 AM, Willy Tarreau <w@1wt.eu> wrote: >> >> >> > Note the last sentence : "*If* the client has an outstanding request ...". >> >> >> > For me that clearly means that the client might very well receive a 408 >> >> >> > while it did not have an outstanding request, which implies that no byte >> >> >> > was sent over the wire yet. >> >> >> >> >> >> How does the client receive the unprompted 408 reliably? Should the >> >> >> client be reading the inbound all the time? >> >> > >> >> > When it sends a request, it receives the unprompted 408 which was sitting >> >> > in the buffers, there's no desynchronization here. As Amos stated it, if >> >> >> >> I'm not sure how it works. Presumably the client has received server >> >> FIN before it starts to write the request. >> > >> > It needs to consume the response to be aware of the FIN. >> > >> >> This likely results in an >> >> RST, which destroys the client's inbound buffer as well. >> > >> > No, the RST is emitted if the server has totally closed (ie: the socket >> > buffers are destroyed and the socket orphan has been killed). >> >> The server intends to kill the idle connection and free the resources, >> correct? Then the client will get RST when it tries to write to the >> connection; > > No, it will first get the response which is already present in its > buffers, the RST will happen at best one RTT after the request is sent. > That's exactly why so many people were recently seeing the 408 in their > browser. Got it. However, RST is still very likely for requests with bigger payloads. If a client wants to reliably receive unprompted 408s, it better proactively poll the inbound. In that case, I argue that FIN is as good as 408, because the client agent knows that the server closed the connection before the client sends (or is about to send) the request, therefore it's safe to retry the request. We could argue that unprompted 408 is beneficial for most requests (of moderate size). However, if browsers need to be patched to take advantage of 408, they are better off to spend the effort to handle the more general case - proactively poll the inbound, discard the connection immediately if anything is received without a request (mostly FIN). > >> if the client tries to read from the connection >> afterwards, it'll likely fail as well, depending on the TCP stack. > > Once the RST reaches the client, it will fail. But before that the > pre-queued response will be delivered. And I don't see any reason > why a client would send, decide to wait an arbitrary delay, then > receive. The client sends the request and immediately polls for > receive, then it immediately gets the queued response. > >> >> If the client is monitoring its inbound all the time for ahead-of-time >> >> response, we don't need 408 either - the server FIN serves the same >> >> purpose. >> > >> > No, the FIN alone tells you that anything happened, first thing being the >> >> The FIN is received before the client writes the request. It's safe to >> infer that the request is not being processed the server. A reasonable >> server will not close its outbound, then read and process another >> request. > > The problem is not when the FIN reaches the client early. The problem is > that in many circumstances, this FIN will be sent in parallel to the late > request, and will then reach the client *after* the request was sent, while > it was sent *before* the request reached the server. That's the race Amos > was speaking about, and which is even documented in p1-6.5 : > > http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-26 > > For example, a client might have started to send a new request > at the same time that the server has decided to close the "idle" > connection. From the server's point of view, the connection is being > closed while it was idle, but from the client's point of view, a > request is in progress. > > Regards, > Willy >
Received on Wednesday, 4 June 2014 23:24:46 UTC