RE: Sticky headers and pipelining (was: Sticky header draft -- as an attachment)

>----------
>From: 	Jeffrey Mogul[SMTP:mogul@pa.dec.com]
>Sent: 	Wednesday, August 07, 1996 12:52 PM
>To: 	Paul Leach
>Cc: 	'http-wg'
>Subject: 	Re: Sticky headers and pipelining (was: Sticky header draft -- as
>an attachment) 
>
>I wrote:
>>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>
>
>Paul replied (I've reordered things a little):
>    I don't see the ambiguity in this example. [...]
>    I think maybe your example was just buggy (or not clear to me). If the
>    client had sent the second request _before_ it got the reply from the
>    server, then it would have been ambiguous as to whether
>    "Accept-Language: en" was omitted from the request.
>
>I think my example wasn't expressed quite right.  Not exactly
>"buggy", but not clear enough.  I meant that the server would
>transmit its "Connection: sticky" response at the point given,
>but I did not mean to imply that the client necessarily received
>it before making its second request.

OK. That's what I assumed in my reply.
>
>    The server doesn't need to know when the client received
>	    Connection: sticky
>    instead, the client has to send requests that are unambiguous. I.e.,
>    until it receives the
>	    Connection: sticky
>    it sends ALL headers that have ever been sent, which is unambiguous --
>    even if the server thinks that the client *could* be omitting headers,
>    none are actually omitted, so the server won't be confused.
>
>I think this rule, which was not stated in your draft (as far as I
>can tell) is almost right.

You're right, it isn't in the draft; I wasn't focussed on pipelining
when I wrote it.

>  The problem is that, as stated, it might
>require the client to send inappropriate headers for certain requests
>(if, for example, the client's preferences varied based on some aspect
>of the request-URL).  I would much prefer a more cautious specification,
>that would work correctly independently of any assumptions we might
>make know about the semantics of the request headers.

This time it is I who wasn't clear. 

Regardless of the pipelining issue, when using sticky headers, a client
always has to have a way to say
	"you know that header I sent in the last message -- it just isn't in
this message"

The mechanism for that in the draft is that the client sends the header
name and an empty value, which means that, even though there was a value
for that header in the last message, this message should be interpreted
as if the header with that field-name is not present in the message.

There must be some mechanism like this, independent of the semantics of
any request header, in order for sticky headers to work at all.

>Applying the above to your claim that "it might require the client to send
inappropriate headers for certain requests" I hope it is not too hard to
see that the client can never be forced to send a header it doesn't want
to, because it has to have (by the nature of sticky headers) to not send
any given header.

Now, you could object that the mechanism I chose to allow a client to
not send a header is a bad one -- it does make one assumption about the
semantics of all headers -- that an empty value is never legal.
I.e. it must be the case, if Foo is to be used as a sticky header, that
	Foo:<CRLF>
is unambiguous, and means that even if there was a Foo header in the
previous message, this message should be interpreted as if there were no
Foo header, for all headers Foo.

One could invent a header with the property that (say)
	Foo:<CRLF>
meant one thing, and
	Foo: Yes
meant another. I don't believe that are currently any examples of this,
however. Certainly, either we would either have to outlaw adding any
such headers to HTTP, or outlaw their participation in the sticky header
mechanism.

>
>    >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.)
>    
>    I agree it needs to be per connection. I don't see why it has to
>    wait the extra round trip. I think the modification above solves
>    the problem.  If a client were _required_ to omit headers that were
>    the same as in the last message once it had received the
>    "Connection: sticky" from the server, then I think there would need
>    to be tighter synchorization.
>
>I'm not sure how to interpret that paragraph.  Does "the modification
>above" refer to my #1, or your "the client has to send requests that
>are unambiguous"?  If the latter, I would appreciate a careful 
>definition of "unambiguous."   I'm not sure that "ALL headers that
>have ever been sent" really works.

It is the latter. What I meant by "unambiguous" is that the client's
requests are unambiguous if the server need not know when the client
received the response that agreed to sticky headers in order to process
the requests properly. The rule "ALL headers that have ever been sent"
was not intended to be "spec-quality". To elaborate a bit, but still not
spec quality (it takes me a while longer to write spec-quality prose),
until the client receives the reponse from the server, in each message
that it sends, for each header in the message,
if any previous message had a value for the header, this message has to
either have a value for that header, or use the "Foo:<CRLF>" encoding to
indicate that it is intended that the header not be present. In
particular, it can't omit headers whose value is the same as in the last
message.

The first time I read your suggestion about the three way handshake, the
above seemed simpler, and didn't require the extra bytes of the second
Connection: sticky (and I didn't understand #1 above). But I'm not so
sure now that the handshake isn't easier to explain and implement.

Paul 

Received on Wednesday, 7 August 1996 14:44:44 UTC