- From: Jeffrey Mogul <mogul@pa.dec.com>
- Date: Mon, 05 Aug 96 13:22:07 MDT
- To: Paul Leach <paulle@microsoft.com>
- Cc: 'http-wg' <http-wg%cuckoo.hpl.hp.com@hplb.hpl.hp.com>
Your draft says:
The negotiation of the sticky headers option may take place on any
request sent over a persistent connection. The client may add the
connection-token "Sticky" to the Connection header in a request; if the
server accepts the use of sticky headers, it responds with the same
token in the Connection header of its response.
Once the use of sticky headers has been negotiated, specified message-
headers (see section 4.1 and 4.2 of [1]) are remembered from message to
message, so that they need to be transmitted in a message only if they
have changed since the last message. The use of sticky headers continues
until the connection is closed, without further need for the "Sticky"
connection-token on each request.
I think this leads to an ambiguous situation when the client is
pipelining requests. We identified this ambiguity at the meeting
we had in January of the persistent-connections subgroup.
Consider this **somewhat contrived** example
client:
## requesting first object, negotiating sticky headers ##
GET / HTTP/1.1<CRLF>
Accept: text/html<CRLF>
Accept-Language: en<CRLF>
Connection: sticky<CRLF>
<CRLF>
server:
HTTP/1.1 200 OK<CRLF>
MIME-Version: 1.0<CRLF>
Connection: sticky<CRLF>
Content-Type: text/html<CRLF>
Content-Length:94<CRLF>
<CRLF>
<94 bytes body data here>
client:
## requesting second object, changing one of the to-be-sticky headers ##
GET /a.gif HTTP/1.1<CRLF>
Accept: image/gif<CRLF>
<CRLF>
## requesting 3rd object, again changing 1 of the to-be-sticky headers ##
GET /b.jpeg HTTP/1.1<CRLF>
Accept: image/jpeg<CRLF>
## requesting 4th object, not sending one of the to-be-sticky headers ##
GET /c.gif HTTP/1.1<CRLF>
<CRLF>
OK, so what are the effective request headers for the 4th request?
Your design implicitly disallows the client from assuming "stickiness"
until it has received
Connection: sticky<CRLF>
from the server. However, because there is no way for the server
to tell whether the client received that header before or after
sending the fourth request, the server cannot unambiguously know
what the client means (i.e., should the fourth request be interpreted
as having "Accept: image/jpeg" or not?)
One could argue that this kind of thing could never happen in practice,
and so my contrived example (which admittedly is pretty foolish on the
part of the client) is not worth discussing. But the race condition
seems to be intrinsic in the current draft design, and I'd feel more
confident if there were either a proof that it is not really a problem,
or a design modification that prevented the ambiguity.
I can see several possible ways to solve this:
(1) Explicitly declare that the client, after having sent
"Connection: sticky", may start omitting headers as soon as it
receives the server's "Connection: sticky" response, but MUST
NOT change any such headers before receiving a response to the
first request sent *after* it has received that "Connection:
sticky" response from the server. This rule has to be
interpreted "per connection". (If you draw out the timing
diagram, you can see that this will always avoid the race
condition.)
(2) Change the proposed protocol so that the client explicitly
signals to the server that negotiation is over and it is
starting to use the sticky-header mechanism. This is
similar to how Telnet negotiation works. E.g.,
client sends
Connection: want-sticky ->
server replies
<- Connection: sticky-OK
client sends
Connection: doing-sticky ->
immediately after which the client can start taking full
advantage of the sticky-header mechanism, one RTT sooner than
with option #1. You could still get by with a single "sticky"
token, by adopting the rule that the client must send it a
second time, but only after receiving it from the server.
Regarding:
2.2 Contexts
Proxies can operate just like user-agents if they want. However, they
typically act on behalf of many clients, multiplexing a single
connection to a server across messages from many clients. Such
multiplexing will likely destroy the correlation between consecutive
messages that makes sticky headers an effective compression technique.
It might be a good idea for you to provide a means for negotiating
multiple contexts over a single proxy-server connection, but I am
not sure it's wise to implicitly bless the multiplexing of request
streams from several clients. This can lead to something akin to
the "head of line blocking" problem seen in network switches:
Head of line blocking occurs when a packet at the head of an input
queue blocks, thereby preventing a packet behind it from using an
available output port. The problem is common to networks which
employ input FIFOs which prevent packets from passing one another.
The solution to head of line blocking is to use random access
buffers which permit packets to be forwarded out of order.
quoted from "High Performance Communication for Distributed Systems"
by William Stasior,
http://www.tns.lcs.mit.edu/~wstasior/distrib_sys_comm/distrib_sys_comm.html
Consider the case where proxy P is combining request streams from
client C1 and client C2 over the same TCP connection to server S.
Since we don't allow reordering of requests (i.e., we use "input FIFOs"
at the server side), if C2 makes a request that takes a long time to
answer, C1 may have to wait even though there is no intrinsic reason
for this. The situation is especially bad if S is actually proxy
as well, and C1 and C2 are really making their requests to unrelated
origin servers S1 and S2. If S2 is down, the C1->S1 request is stalled
until the C2->S2 request times out.
This is why draft-ietf-http-v11-spec-06.txt says
8.1.4 Practical Considerations
[...] A proxy SHOULD use up to 2*N connections to another
server or proxy, where N is the number of simultaneously active
users. These guidelines are intended to improve HTTP response
times and avoid congestion of the Internet or other networks.
-Jeff
Received on Monday, 5 August 1996 13:28:33 UTC