cURL / Mailing Lists / curl-users / Single Mail


[ curl-Bugs-862835 ] Libcurl request returns HTTP/1.1 411 Length Required error

From: <>
Date: Fri, 19 Dec 2003 02:22:10 -0800

Bugs item #862835, was opened at 2003-12-19 02:22
Message generated for change (Tracker Item Submitted) made by Item Submitter
You can respond by visiting:

Category: libcurl
Group: wrong behaviour
Status: Open
Resolution: None
Priority: 5
Submitted By: Nobody/Anonymous (nobody)
Assigned to: Daniel Stenberg (bagder)
Summary: Libcurl request returns HTTP/1.1 411 Length Required error

Initial Comment:
The library version being used is 7.11.0-20031217. Compiled
under OS X 10.2.8 with --disable-ipv6.

When curl issues a PUT (or other custom header the pushes
data) is not including the "Content-Length" header initially.
This causes a HTTP 411 Length Required error to be returned
by the server. With our users it seems to be a problem with
IIS 6.0 on Windows 2003. On Windows 2000, IIS 5.0
responds with a challenge request and when the properly
authenticated request (e.g. PUT) is reissued it does contain
the "Content-Length" header and succeeds as expected.

We do not have enough knowledge of curl to propose a fix
we are sure would not break something else. But, we
suspect these lines in http.c introduce the problem:

      /* until the auth is done, pretend we only do GET */
      httpreq = HTTPREQ_GET;
      httpreq = data->set.httpreq;

This will cause the default case to be hit in the switch
statement that follows and since that case treats the request
like a GET the header is obviously not set.

Here is the curl log illustrating the error as reported by a
user (slightly censored):

* About to connect() to port 443
* Connected to ( port 443
* error setting certificate verify locations, continuing
* CAfile: /usr/local/share/curl/curl-ca-bundle.crt
  CApath: none
* SSL connection using RC4-MD5
* Server certificate:
* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
* start date: 2003-08-14 23:30:43 GMT
* expire date: 2005-08-13 23:30:43 GMT
* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
* SSL certificate verify result: 20, continuing anyway.
> PUT /exchange/kevin/Calendar/
982F-000393A56668-RID%7D.eml HTTP/1.1
User-Agent: Snerdware Groupcal/1.0 (MSIE 6.0; Windows
NT 5.1)
Pragma: no-cache

< HTTP/1.1 411 Length Required
< Content-Type: text/html
< Date: Thu, 18 Dec 2003 02:33:37 GMT
< Connection: close
< Content-Length: 24
* Closing connection #0

The issue is clearly that you don't know in what, if any,
authentication will be required in advance. The "fake" GET is
clearly a problem waiting to happen since the METHOD is
still PUT, SEARCH, PROPFIND or whatever. Curl really needs
to be doing a true PUT (or whatever) but with just the
headers. It should then send the body only if it receives an
HTTP 100 Continue response.
talks about the use of sending a "Expect: 100-continue"
header to achieve this.

This older (1996) RFC
1.1/spec.html#PUT talks about the responsibilities of the
client as being:

HTTP/1.1 allows for a two-phase process to occur in
accepting and processing a PUT request. An HTTP/1.1 client
must pause between sending the message header fields
(including the empty line signifying the end of the headers)
and sending the message body; the duration of the pause is
five (5) seconds or until a response is received from the
server, whichever is shorter. If no response is received
during the pause period, or if the initial response is 100
(continue), the client may continue sending the PUT request.
If the response indicates an error, the client must
discontinue the request and close the connection with the
server after reading the response.

Upon receipt of a PUT request, the server must examine the
header fields and determine whether or not the client should
continue its request. If any of the header fields indicate the
request is insufficient or unacceptable to the server (i.e.,
will result in a 4xx or 5xx response), or if the server can
determine the response without reading the entity body
(e.g., a 301 or 302 response due to an old Request-URI ),
the server must send that response immediately upon its
determination. If, on the other hand, the request appears (at
least initially) to be acceptable and the client has indicated
HTTP/1.1 compliance, the server must transmit an interim
100 response message after receiving the empty line
terminating the request headers and continue processing the
request. After processing has finished, a final response
message must be sent to indicate the actual result of the
request. A 100 response should not be sent in response to
an HTTP/1.0 request except under experimental conditions,
since an HTTP/1.0 client may mistake the 100 response for
the final response.

For compatibility with HTTP/1.0 applications, all PUT
requests must include a valid Content-Length header field
unless the server is known to be HTTP/1.1 compliant. When
sending a PUT request to an HTTP/1.1 server, a client must
use at least one of: a valid Content-Length , a multipart
Content-Type, or the "chunked" Transfer-Encoding . The
server should respond with a 400 (bad request) message if
it cannot determine the length of the request message's
content, or with 411 (length required) if it wishes to insist on
receiving a valid Content-Length .

I realize that is out of date but I couldn't find a
corresponding section in a newer RFC and thought it might
be helpful anyway.


You can respond by visiting:

This email is sponsored by: IBM Linux Tutorials.
Become an expert in LINUX or just sharpen your skills. Sign up for IBM's
Free Linux Tutorials. Learn everything from the bash shell to sys admin.
Click now!
Received on 2003-12-19