cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: More on POST and PUT with 100-continue

From: Jamie Lokier <jamie_at_shareable.org>
Date: Tue, 3 Aug 2004 15:37:27 +0100

Daniel Stenberg wrote:
> >Of course the client can always close the connection if it knows the
> >request is large and being discarded.
>
> Not if using NTLM, since that authenticates *connections*.

Are you sure? A proxy can split the two requests among two origin
server connections, so how can that be reliable?

(It's a fundamental property of HTTP that each request on a connection
should be independent).

> >What about when an ordinary PUT/POST returns an error code or even a
> >redirect?
>
> That's distinguishble from other error codes so they don't (or at least
> shouldn't) cause any problems.

Won't libcurl reuse the connection for another request after the
failed PUT/POST? If it hasn't sent the request body, then the other
(independent) request will be mis-parsed by the proxy or server.

> >Won't libcurl do the wrong thing then, or does it always close and use a
> >new connection, or not use 100-continue, in those cases?
>
> 100-continue is of course used then too, since it can't know on beforehand
> that it'll get redirected.

Not just redirects: any PUT/POST error will trigger this if libcurl
re-uses the connection after the error. Does it do that?

> I'm not sure that all aspects of this is taken care of properly, and I
> guess I won't be until we get more test cases written or users trying them
> out on live servers.

Ok, I've just done some tests. cURL 7.12.0 connection to Apache 2.0.40.

I tried to upload a file to a server of mine which is known to accept
uploads, given a user and correct password.

This is the command I used:

    curl --digest --user 'jamie:wrong_password' --trace /tmp/trace -T test http://shareable.org/testfile

Guess what? It failed totally to upload the file -- or even to try
(cURL doesn't get as far as issuing a PUT request!).

cURL issues a HEAD request. The response from the server is a 302
redirect to www.shareable.org.

Then cURL issues a HEAD request again, to the _same_ address
(shareable.org not www.shareable.org). In other words it doesn't
follow the redirect. Also, the trace contains the following messages:

== Info: Closing connection #0
== Info: Issue another request to this URL: 'http://shareable.org/testfile'
== Info: Disables POST, goes with GET

The message should say PUT not POST, and also it is an error to
convert the PUT to GET due to a 302 redirect. (This is only done for
303 redirects).

Then cURL proceeds by repeating the same HEAD request, to the same
URL. The second HEAD request recieves a 302 or course, because it's
identical to the first one (cURL doesn't follow the redirect). Then
cURL just closes the second connection and terminates, with no error
output to indicate that it failed to upload the file.

So I try again, using this command (the domain is now
www.shareable.org and won't redirect):

    curl --digest --user 'jamie:wrong_password' --trace /tmp/trace -T test http://shareable.org/testfile

Guess what? This fails to upload as well. There is no redirect this
time. And, as before, cURL doesn't produce any error output to
indicate that it failed.

This time cURL issues a HEAD request, and the server responds with 404
Not Found. It's correct -- we're trying to upload a new resource.

cURL just gives up. It doesn't try the PUT request, and also doesn't
produce an error message.

Summary:

    1. redirection with PUT is broken.
    2. digest authentication with PUT is broken as well.

The latter is caused by attempting to use HEAD to start authentication.

(This doesn't really test 100-continue -- these two cURL tests didn't
get that far. But otherwise I found that Apache 2.0.40,
unfortunately, issues 100 Continue unconditionally, even when it's
responding with an error or redirect. That is rather stupid. I think
Apache 1.3 doesn't, but I don't have that any more).

-- Jamie
Received on 2004-08-03