On Sat, Aug 23, 2008 at 5:51 AM, Oleg Kalnichevski <[EMAIL PROTECTED]> wrote:
> On Fri, 2008-08-22 at 18:01 -0400, Bill Higgins wrote:
>> We have been working on a little proxy server that sits between a
>> browser and a backend data server. We take an incoming HTTP request
>> from the browser (type HttpRequest) and copy them into a new proxy
>> HTTP Request (also type HttpRequest). We use Apache HTTP Client within
>> our server to send the new proxy HTTP Request to the remote server.
>>
>> Our code currently blindly copies the incoming browser request's
>> headers into the headers of the outgoing proxy request. On
>> content-enclosing requests, this leads to an unexpected exception for
>> PUT and POST requests:
>>
>> org.apache.http.ProtocolException: Content-Length header already present
>>
>> We stepped through the code and realized that the error happens in
>> org.apache.http.protocol.RequestContent#process. The stanza that
>> throws the exception is this one:
>>
>> if (request instanceof HttpEntityEnclosingRequest) {
>> // ...
>> if (request.containsHeader(HTTP.CONTENT_LEN)) {
>> throw new ProtocolException("Content-Length header already
>> present");
>> }
>>
>> It appears like the RequestContent wants to set the request's
>> Content-Length header itself based on the contents of its entity. But
>> we're setting it at the request level because we're acting as a
>> transparent proxy and the browser already told us what the
>> content-length was.
>>
>> So I understand the rationale but it almost feels like you're being
>> too paranoid and penalizing code that knows what it's doing. For now
>> we'll just remove all of the headers that RequestContent doesn't seem
>> to like, but it seems wrong that we have to read the code to
>> understand what's allowed and not allowed.
>>
>> Here's what we'd prefer (in order of preference):
>> 1) If you can compute the length of the entity within Java code, just
>> overwrite whatever's on the incoming request
>> 2) Trust the content-length a client sends in
>> 3) Document that you're not supposed to set the content-length at the
>> request level when using HttpClient
>>
>> Please let me know what you think - maybe I'm missing something (it
>> wouldn't be the first time).
>>
>
> Bill,
>
> Well behaved proxies should handle so called hop by hop headers with
> care and certainly must not blindly send them to the next hop. See
> section 13.5.4
>
> http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html
>
> It is strongly advised to remove hop by hop headers and let HttpClient
> re-generate them based on the composition of the request. Sometime proxy
> may need to downgrade from HTTP/1.1 to HTTP/1.0 or visa versa. In this
> case, for instance, HttpClient will automatically convert chunk-coded
> entities to content-length delimited or the other way around.
>
> Alternatively, just plug in a custom version of RequestContent
> interceptor.
>
> Hope this helps
>
> Oleg
>
Thanks for the response. It was informative, but I think there's still an issue.
RequestContent was throws an exception if either "Content-Length" or
"Transfer-Encoding". The HTTP spec section that talks about end-to-end
and hop-by-hop headers
(http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1)
enumerates eight headers as hop-by-hop headers and declares everything
but those eight to be end-to-end headers. "Transfer-Encoding" is
listed as one of the eight hop-by-hop headers, but "Content-Length" is
not.
I take your point to heart about not blindly copying over all headers
(and I'll change my code as a result), but that's a separate issue
from ResponseContent's behavior to throw an exception if the request
already has a "Content-Length" header set. If the behavior of
RequestContent is based on the HTTP spec's statements about hop-by-hop
and end-to-end headers, then its current behavior vis-a-vis
already-set "Content-Length" header would seem to be a bug.
Thoughts?
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]