Re: [Fwd: I-D ACTION:draft-decroy-http-progress-00.txt]

Henrik Nordstrom wrote:
> tis 2007-02-13 klockan 12:58 +1300 skrev Adrien de Croy:
>
>   
>> then the problem can still be clearly shown.
>>
>> 1. Client wants to post to server.
>> 2. client connects to proxy, sends initial request, but not body
>> 3. client waits for 100 continue.
>> 4. proxy evaluates request, DNS and policy lookups etc. some time elapses.
>> 5. Proxy Initiates connection to sever.. some more time elapses.
>> 6. Client stops waiting for 100 continue and starts sending body
>> 7. proxy achieves connection, server sends 401 auth required
>> 8. proxy passes back 401 auth required
>> 9. client has to terminate connection and start again.
>>     
>
> Well.. no matter what the client only has the choice of either closing
> the connection or sending the request body. That's the only two
> available options once the request headers have been sent indicating
> there will be a request entity body.
>   

There is another option.  Waiting for a 100 Continue before sending 
message body.

> Adding a new "Defer" status code does not change this, and is why I got
> confused by your draft into thinking that you somehow proposed that the
> client should change how it sends the request body.
>   

At the moment, a client wishing to submit a POST or PUT with a request 
body has 3 options after
sending the request headers.

1. immediately send the request body (in contradiction to RC2616, which 
says it should wait for a 100 continue)
2. wait for a period of time for a 100 continue, if it doesn't receive 
one soon enough, send the body.
3. wait indefinitely for a 100 continue before sending the request body.

1 is in contradiction to RFC2616.
At the moment, no clients choose 3, because that would be pointless if 
the server was never going to send 100 continue

The aim of the defer status is to remove option 2.  So there is then 
ONLY option 3.  The client must wait
for a 100 continue (whilst still keeping the connection open) before 
sending the request body.

So, if you have a client that honours a 1xx defer status.

case 1, proxy requires auth, server does not.

1. Client sends request headers only (as per current RFC2616 
suggestions) and goes into a short wait state
2. proxy sees that there will be a request body, so immediately sends 
"HTTP/1.1 1xx wait please"
3. client terminates timer for when it would otherwise send request 
body.  It does not send request body
4 proxy then sends "HTTP/1.1 407 auth required"
5 client establishes auth credentials with proxy, still not sending 
request body6 proxy connects to upstream server. 
7. server sends 100 continue
8 proxy sends server response back through to client
9 client sends request body
10 proxy relays request body.
11. server sends 200 ok.
12. proxy relays 200 ok.
13 done.

case 2, proxy requires auth, and server also requires auth.

1. Client sends request headers only (as per current RFC2616 
suggestions) and goes into a short wait state
2. proxy sees that there will be a request body, so immediately sends 
"HTTP/1.1 1xx wait please"
3. client terminates timer for when it would otherwise send request 
body.  It does not send request body
4 proxy then sends "HTTP/1.1 407 auth required"
5 client establishes auth credentials with proxy, still not sending 
request body
6 proxy connects to upstream server. 
7. server sends 401 auth required
8 proxy sends server response back through to client
9 client resends request with server credentials  Still no request body
10 proxy relays request to server
11. server sends 100 continue
12. proxy relays 100 continue
13. client sends request body
14 proxy relays request body
15 server sends 200 ok
16 proxy relays 200 ok.
17 done.

case 3, only server requires auth

1. Client sends request headers only (as per current RFC2616 
suggestions) and goes into a short wait state
2. proxy sees that there will be a request body, so immediately sends 
"HTTP/1.1 1xx wait please"
3. client terminates timer for when it would otherwise send request 
body.  It does not send request body
4 proxy connects to upstream server. 
5. server sends 401 auth required
6 proxy sends server response back through to client
7 client resends request with server credentials  Still no request body
8 proxy relays request to server
9. server sends 100 continue
10. proxy relays 100 continue
11. client sends request body
12 proxy relays request body
13 server sends 200 ok
14 proxy relays 200 ok.
15 done.

You can see that all three cases, steps 1 - 3 are the same, and the 
steps for server auth, and proxy auth are the same.

Also, step 1 is that proposed by RFC2616. Send and wait before sending 
the request body.

 From the client's point of view, once it has received a 102 wait 
please, it won't send any request body unless it receives
a 100 continue.  If it receives anything else, it will process that.

All this can be done on the same connection between client and proxy, 
proxy and server.

I should really draw up a flow chart of all this.  from the client's 
point of view, it sends a request, and if it receives a 102
wait please, it will then receive any number of:

a. a 100 continue
b. an auth challenge
c. some failure code indicating the request is denied.
d. connection closed (some failure condition)..

until it has received a 100 continue however, it won't send the request 
body.

This is the only way to guarantee that the request body will only ever 
be transmitted once, no matter how many steps
must be taken before it is "safe" for the client to transmit the body.

This method scales to any number of chained elements and any number of 
auth steps, redirects etc etc etc.

>   
>> At least with basic auth, the credentials can be submitted the second time.
>>     
>
> Yes. And the same for Digest or any other message based authentication
> scheme following the HTTP/1.1 protocol requirements.
>
>   

I think with the way security and encrytion are moving, we are moving 
more towards negotiation of credentials
on a per-connection basis.  Reuse of any crypto derived information is 
normally seen as a vulnerability, so being
able to reuse nonces etc is arguably a security hole.  I see pressure to 
move towards a nonce per connection, or in
other words session-based credentials like NTLM.  Therefore I see this 
"problem" growing rather than shrinking.

>> If the intermediary is an intercepting proxy however, and requires auth 
>> (even basic)
>> then breaking the connection will lose the auth either to the server or 
>> proxy,
>> since there can't be 2 sets of Authorization tags, and so this situation 
>> prevents
>> operation completely unless the client sends chunked data as you've 
>> suggested.
>>     
>
> An intercepting proxy can not use HTTP auth as HTTP proxy auth is only
> possible when following specifications.
>   
There are many that still do it, and customers wish it.  Are we to deny 
the customers wishes?

> Not a all. It's just that if any hop uses NTLM or other connection
> oriented aurh sceme then closing the connection is not an option so the
> request body MUST be transmitted in order for the authentication to
> work.
>
> The new "defer" status code only avoids situations where the body is
> unneededly transmitted before closing the connection. 
Not just this case "where the body is unneededly transmitted before 
closing the connection" but in
all cases, whether the connection is closed or not, and it is in fact 
the intention of this spec that the
connection remain open.

> It does not at all
> solve the problems of NTLM or other connection oriented authentication
> methods.
>   
yes it does.

>   
>> I am thinking more about your point about using TCP flow control.  We 
>> are able to
>> send a 0 window size, but that won't guarantee that the client won't 
>> enter into the
>> state where it thinks it is sending the body (and would therefore 
>> terminate on
>> any 4xx response).
>>     
>
> Terminating the connection on 4xx is completely unrelated to if the
> client has begun sending the request body or not. That's a property of
> the server response and the preferences of the client just as any other
> request/response pair.
>
> The only way of not having to send the complete request body without
> closing the connection is to use chunked encoding. If Content-Length is
> used then the client MUST either send the indicated amount of data or
> close the connection no matter what response is received.
>   
I think there's still some confusion about what I'm proposing.  
Hopefully that's cleared up with the
3 cases I outlined above.

I'm actually working on building Firefox at the moment.  If it would be 
helpful I can make available
a windows proxy and a windows web browser to actually demonstrate this 
in operation.

Will take me a while though.

Regards

Adrien

> Regards
> Henrik
>   

Received on Tuesday, 13 February 2007 22:42:01 UTC