Why “Content-Length: 0” in POST requests?

2020-01-26 04:58发布

A customer sometimes sends POST requests with Content-Length: 0 when submitting a form (10 to over 40 fields).

We tested it with different browsers and from different locations but couldn't reproduce the error. The customer is using Internet Explorer 7 and a proxy.

We asked them to let their system administrator see into the problem from their side. Running some tests without the proxy, etc..

In the meantime (half a year later and still no answer) I'm curious if somebody else knows of similar problems with a Content-Length: 0 request. Maybe from inside some Windows network with a special proxy for big companies.

Is there a known problem with Internet Explorer 7? With a proxy system? The Windows network itself?

Google only showed something in the context of NTLM (and such) authentication, but we aren't using this in the web application. Maybe it's in the way the proxy operates in the customer's network with Windows logins? (I'm no Windows expert. Just guessing.)

I have no further information about the infrastructure.

UPDATE: In December 2010 it was possible to inform one administrator about this, incl. links from the answers here. Contact was because of another problem which was caused by the proxy, too. No feedback since then. And the error messages are still there. I'm laughing to prevent me from crying.

UPDATE 2: This problem exists since mid 2008. Every few months the customer is annoyed and wants it to be fixed ASAP. We send them all the old e-mails again and ask them to contact their administrators to either fix it or run some further tests. In December 2010 we were able to send some information to 1 administrator. No feedback. Problem isn't fixed and we don't know if they even tried. And in May 2011 the customer writes again and wants this to be fixed. The same person who has all the information since 2008.

Thanks for all the answers. You helped a lot of people, as I can see from some comments here. Too bad the real world is this grotesque for me.

UPDATE 3: May 2012 and I was wondering why we hadn't received another demand to fix this (see UPDATE 2). Looked into the error protocol, which only reports this single error every time it happened (about 15 a day). It stopped end of January 2012. Nobody said anything. They must have done something with their network. Everything is OK now. From summer 2008 to January 2012. Too bad I can't tell you what they have done.

UPDATE 4: September 2015. The website had to collect some data and deliver it to the main website of the customer. There was an API with an account. Whenever there was a problem they contacted us, even if the problem was clearly on the other side. For a few weeks now we can't send them the data. The account isn't available anymore. They had a relaunch and I can't find the pages anymore that used the data of our site. The bug report isn't answered and nobody complaint. I guess they just ended this project.

UPDATE 5: March 2017. The API stopped working in the summer of 2015. The customer seems to continue paying for the site and is still accessing it in February 2017. I'm guessing they use it as an archive. They don't create or update any data anymore so this bug probably won't reemerge after the mysterious fix of January 2012. But this would be someone else's problem. I'm leaving.

13条回答
小情绪 Triste *
2楼-- · 2020-01-26 05:10

Microsoft's hotfix for KB821814 can set Content-Length to 0:

The hotfix that this article describes implements a code change in Wininet.dll to:

  • Detect the RESET condition on a POST request.
  • Save the data that is to be posted.
  • Retry the POST request with the content length set to 0. This prevents the reset from occurring and permits the authentication process to complete.
  • Retry the original POST request.
查看更多
可以哭但决不认输i
3楼-- · 2020-01-26 05:10

We have a customer on our system with exactly the same problem. We've pin pointed it down to the proxy/firewall. Microsoft's IAS. It's stripping the POST body and sending content-length: 0. Not a lot we can do to work around however, and down want to use GET requests as this exposes usernames/passwords etc on the URL string. There's nearly 7,000 users on our system and only one with the problem... also only one using Microsoft IAS, so it has to be this.

查看更多
闹够了就滚
4楼-- · 2020-01-26 05:12

I also had a problem where requests from a customer's IE 11 browser had Content-Length: 0 and did not include the expected POST content. When the customer used Firefox, or Chrome the expected content was included in the request.

I worked out the cause was the customer was using a HTTP URL instead of a HTTPS URL (e.g. http://..., not https://...) and our application uses HSTS. It seems there might be a bug in IE 11 that when a request gets upgraded to HTTPS due to HSTS the request content gets lost.

Getting the customer to correct the URL to https://... resulted in the content being included in the POST request and resolved the problem.

I haven't investigated whether it is actually a bug in IE 11 any further at this stage.

查看更多
霸刀☆藐视天下
5楼-- · 2020-01-26 05:16

If the user is going through an ISA proxy that uses NTLM authentication, then it sounds like this issue, which has a solution provided (a patch to the ISA proxy)

http://support.microsoft.com/kb/942638
POST requests that do not have a POST body may be sent to a Web server that is published in ISA Server 2006

查看更多
可以哭但决不认输i
6楼-- · 2020-01-26 05:16

We had a customer using same website in anonymous and NTLM mode (on different ports). We found out that in our case the 401 was related to Riverbed Steelhead application used for http optimization. The first signal pointing us into that direction was a X-RBT-Optimized-By header. The issue was the Gratuitous 401 feature:

This feature can be used with both per-request and per-connection authentication but it‘s most effective when used with per-request authentication. With per-request authentication, every request must be authenticated against the server before the server would serve the object to the client. However, most browsers do not cache the server‘s response requiring authentication and hence it will waste one round-trip for every GET request. With Gratuitous 401, the client-side Steelhead appliance will cache the server response and when the client sends the GET request without any authentication headers, it will locally respond with a ―401 Unauthorized‖ message and therefore saving a round trip. Note that the HTTP module does not participate in the actual authentication itself. What the HTTP module does is to inform the client that the server requires authentication without requiring it to waste one round trip.

查看更多
ゆ 、 Hurt°
7楼-- · 2020-01-26 05:17

There's a good chance the problem is that the proxy server in between implements HTTP 1.0.

In HTTP 1.0 you must use the Content-Length header field: (See section 10.4 here)

A valid Content-Length is required on all HTTP/1.0 POST requests. An HTTP/1.0 server should respond with a 400 (bad request) message if it cannot determine the length of the request message's content.

The request going into the proxy is HTTP 1.1 and therefore does not need to use the Content-Length header field. The Content-Length header is usually used but not always. See the following excerpt from the HTTP 1.1 RFC S. 14.13.

Applications SHOULD use this field to indicate the transfer-length of the message-body, unless this is prohibited by the rules in section 4.4. Any Content-Length greater than or equal to zero is a valid value.

Section 4.4 describes how to determine the length of a message-body if a Content-Length is not given.

So the proxy server does not see the Content-Length header, which it assumes is absolutely needed in HTTP 1.0 if there is a body. So it assumes 0 so that the request will eventually reach the server. Remember the proxy doesn't know the rules of the HTTP 1.1 spec, so it doesn't know how to handle the situation when there is no Content-Length header.

Are you 100% sure your request is specifying the Content-Length header? If it is using another means as defined in section 4.4 because it thinks the server is 1.1 (because it doesn't know about the 1.0 proxy in between) then you will have your described problem.

Perhaps you can use HTTP GET instead to bypass the problem.

查看更多
登录 后发表回答