My favorites | Sign in
Project Logo
          
New issue | Search
for
| Advanced search | Search tips
Issue 114: Unable to POST with missing "Content-Length" header (for "Transfer-Encoding: chunked" requests)
10 people starred this issue and may be notified of changes. Back to list
Status:  Fixed
Owner:  ----
Closed:  Apr 2009
Type-Defect
Priority-Medium
Milestone-2.1.4


Sign in to add a comment
 
Reported by nat...@atnan.com, Jul 31, 2008
What steps will reproduce the problem?

1. Make a POST request using "Transfer-Encoding: Chunked"

What is the expected output? What do you see instead?

The POST request should be successful. Instead, I receive a "HTTP/1.1 411
Length Required" response.

What version of the product are you using? On what operating system?

I'm running Ubuntu 7.10, Apache 2.2.4 and Passenger 2.0.2.

Please provide any additional information below.

Many mobile devices will make POST requests using "chunked" as the transfer
encoding, since their memory constraints may prohibit them from being able
to determine the full content-length at request time. Apache 1 had
difficulties with chunked POST requests due to relying on content-length,
but Apache 2 has since resolved the problem as per the requirements of HTTP
1.1 ("All HTTP/1.1 applications MUST be able to receive and decode the
"chunked" transfer-coding").

It seems as though Passenger is still using the Apache 1.3 API
(ap_setup_client_block on line 651 of ext/apache2/Hooks.cpp), which means
that the minute it sees a request missing a content-length parameter, it
immediately responds with "411 Length Required".

Unfortunately, I have no C++ *or* Apache experience, so I'm not really able
to help fix the problem.

The following is the output of running CURL, with and without chunked
encoding enabled:

$ curl -vvv -F "query=zoooom" --header "Transfer-Encoding: chunked"
http://localhost/stories/search.json
* About to connect() to localhost port 80 (#0)
*   Trying 127.0.0.1... connected
* Connected to localhost (127.0.0.1) port 80 (#0)
> POST /stories/search.json HTTP/1.1
> User-Agent: curl/7.16.4 (i486-pc-linux-gnu) libcurl/7.16.4 OpenSSL/0.9.8e
zlib/1.2.3.3 libidn/1.0
> Host: localhost
> Accept: */*
> Transfer-Encoding: chunked
> Expect: 100-continue
> Content-Type: multipart/form-data;
boundary=----------------------------788d73dee5fa
> 
< HTTP/1.1 411 Length Required
< Date: Thu, 31 Jul 2008 07:44:26 GMT
< Server: Apache/2.2.4 (Ubuntu) Phusion_Passenger/2.0.2
< Content-Length: 337
< Connection: close
< Content-Type: text/html; charset=iso-8859-1
< 
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>411 Length Required</title>
</head><body>
<h1>Length Required</h1>
<p>A request of the requested method POST requires a valid
Content-length.<br />
</p>
<hr>
<address>Apache/2.2.4 (Ubuntu) Phusion_Passenger/2.0.2 Server at localhost
Port 80</address>
</body></html>
* Closing connection #0

$ curl -vvv -F "query=zoooom" http://localhost/stories/search.json 
* About to connect() to localhost port 80 (#0)
*   Trying 127.0.0.1... connected
* Connected to localhost (127.0.0.1) port 80 (#0)
> POST /stories/search.json HTTP/1.1
> User-Agent: curl/7.16.4 (i486-pc-linux-gnu) libcurl/7.16.4 OpenSSL/0.9.8e
zlib/1.2.3.3 libidn/1.0
> Host: localhost
> Accept: */*
> Content-Length: 146
> Expect: 100-continue
> Content-Type: multipart/form-data;
boundary=----------------------------0bf6b81d0f2c
> 
< HTTP/1.1 100 Continue
< HTTP/1.1 200 OK
< Date: Thu, 31 Jul 2008 07:44:40 GMT
< Server: Apache/2.2.4 (Ubuntu) Phusion_Passenger/2.0.2
< X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 2.0.2
< X-Runtime: 0.22812
< ETag: "fea15ab349247b6d18f4975d50c65d12"
< Cache-Control: private, max-age=0, must-revalidate
< Set-Cookie: _sr_session=f812b50fb6c9f16cbb0728c19bc4dbaf; path=/
< Content-Length: 83
< Content-Type: text/javascript; charset=utf-8
< 
* Connection #0 to host localhost left intact
* Closing connection #0
{"YAY": "JSON RETURNED"}

 
Comment 1 by honglilai, Jul 31, 2008
Unfortunately I'm not aware of any other way with which Apache modules can receive
POST bodies. The Apache API is not very well documented. If anybody knows how to fix
this, please comment here.
Labels: NeedHelp
Comment 2 by nat...@atnan.com, Aug 03, 2008
I'm not C++ programmer, but from looking around it seems as though you need to change
the way you're using the ap_setup_client_block() API. This means using
REQUEST_CHUNKED_DECHUNK instead of REQUEST_CHUNKED_ERROR, and never assuming that
there is a Content-Length header. I've created a patch with these changes, but it's
causing issues with the ap_content_length_filter (when I make the above chunked
request, only the header of the HTTP request gets delivered to the Rails process and
the body gets dropped with the error: "Connection reset by peer:
ap_content_length_filter: apr_bucket_read() failed").

More competent C++ programmers like yourselves might be able to take this patch and
make it work properly.
dechunk.patch
2.3 KB Download
Comment 3 by honglilai, Aug 04, 2008
Thanks. Are there any web browsers out there that can send POST data in chunked format?

If not, could you use Wireshark or something to capture an HTTP session with chunked
POST data, and attach it here?
Comment 4 by nat...@atnan.com, Aug 05, 2008
I'm not sure whether IE/Safari/Firefox etc. will use "Tranfer-Encoding: Chunked"
under any conditions, but there may be a Firefox extension that allows you to do it.
The alternative is to use curl as follows:

curl -vvv \
-F "query=zoooom" \
--header "Transfer-Encoding: chunked" \
--header "Expect:" \
http://ooboontoo:81/stories/search.json

I've attached the Wireshark output from the above curl command.
request.txt
934 bytes Download
Comment 5 by nat...@atnan.com, Aug 06, 2008
This might be useful for some context:

https://issues.rpath.com/browse/RPL-1174
Comment 6 by honglilai, Aug 07, 2008
Allright, thanks. I don't have time to do this right now, but it's on my todo list.
Comment 7 by nat...@atnan.com, Aug 07, 2008
I've come up with a temporary solution until this is fixed. I'm using mod_proxy with
the "proxy-sendcl" environment variable running on port 80, proxying to a
mod_passenger virtual host running on port 81. I've outlined the problem and solution
here:

http://www.atnan.com/2008/8/8/transfer-encoding-chunked-chunky-http
Comment 8 by stephan.kaag, Feb 10, 2009
Any progress on this?
Comment 9 by honglilai, Feb 10, 2009
Sorry I haven't had the chance to look at this yet. Ping me again in the future if
it's taking too long.
Comment 10 by chiel.wester, Feb 17, 2009
Having issues with this on CentOS in combination with Apache 2.2.3
Any progress yet? 

Comment 11 by stephan.kaag, Feb 17, 2009
* ping
Comment 12 by stephan.kaag, Mar 05, 2009
Seems to be fixed in newest Passenger release!
Comment 13 by james+ol...@lazyatom.com, Mar 24, 2009
I have updated to the latest passenger (2.1.2), but it doesn't seem to be fixed for me:

$ curl -vvv -F "query=zoooom" --header "Transfer-Encoding: chunked" http://mysite.local/
* About to connect() to mysite.local port 80 (#0)
*   Trying 127.0.0.1... connected
* Connected to mysite.local (127.0.0.1) port 80 (#0)
> POST / HTTP/1.1
> User-Agent: curl/7.18.2 (i386-apple-darwin9.3.0) libcurl/7.18.2 zlib/1.2.3
> Host: mysite.local
> Accept: */*
> Transfer-Encoding: chunked
> Expect: 100-continue
> Content-Type: multipart/form-data; boundary=----------------------------5e7066c3b40a
> 
< HTTP/1.1 411 Length Required
< Date: Tue, 24 Mar 2009 09:45:25 GMT
< Server: Apache/2.2.9 (Unix) mod_ssl/2.2.9 OpenSSL/0.9.7l DAV/2 Phusion_Passenger/2.1.2
< Content-Length: 239
< Connection: close
< Content-Type: text/html; charset=iso-8859-1
< 
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>411 Length Required</title>
</head><body>
<h1>Length Required</h1>
<p>A request of the requested method POST requires a valid Content-length.<br />
</p>
</body></html>
* Closing connection #0
Comment 14 by nat...@atnan.com, Mar 25, 2009
For as long as this line exists, the problem hasn't been fixed and you will need to work around it using 
mod_proxy:

http://github.com/FooBarWidget/passenger/blob/master/ext/apache2/Hooks.cpp#L394

If you're familiar with C++, the fix should be trivial and you should take a look at my patch for inspiration.
Comment 15 by honglilai, Apr 01, 2009
This issue has been fixed in commit 5038157db90. The patch was insufficient so I had
to do a bunch of other things as well. Sorry for taking so long.
Status: Fixed
Labels: -NeedHelp Milestone-2.1.4
Comment 16 by nat...@atnan.com, Apr 01, 2009
Thanks Hongli Lai, that's fantastic.
Sign in to add a comment

Hosted by Google Code