Why "Content-Length" header is removed when HTTP response is compressed (GZIP)? - java

Why Content-Length header is removed when HTTP response is compressed using GZIP?
When I set the response headers like:
response.setHeader("Content-Encoding", "gzip");
response.setContentLengthLong(46464);
the Content-Length header is not sent by the GlassFish4 server. My question is - why it is removed?
I'm using java Servlet/3.1.
Response header:
Server: GlassFish Server Open Source Edition 4.1
X-Powered-By: Servlet/3.1 JSP/2.3 (GlassFish Server Open Source Edition 4.1 Java/Oracle Corporation/1.8)
Date: Sat, 28 Nov 2015 19:36:53 GMT
Accept-Ranges: bytes
Connection: keep-alive
Keep-Alive: timeout=1800
Content-Disposition: inline;filename*=utf-8''big-buck-bunny_traixler.webm
ETag: big-buck-bunny_traixler.webm-2165175-1448346083000
Cache-Control: private,max-age=604800
Last-Modified: Tue, 24 Nov 2015 06:21:23 GMT
Content-Encoding: gzip
response.setContentLengthLong(46464); is set after compressed data written to byte array (thus you know compressed data length), and before compressed data are written to output stream and flushed.
Also - Content-Type header is removed...

Related

"Accept-Ranges" header is set to "none" when a spring boot app is hosted in remote VM. It is set to "bytes" when hosted locally

I have a spring boot application which needs to serve range requests for resuming downloads. Things works fine when this spring boot app is hosted in local windows machine and "Accept-Ranges" header is set to "bytes" by default. But when the same application is hosted in a remote virtual machine running windows, "Accept-Ranges" header is set to "none" by default and resuming download is not working. What can be the issue here?
>curl -I http://localhost:8080
HTTP/1.1 200
Accept-Ranges: bytes
Content-Type: application/json
Content-Length: 36121548
Date: Tue, 14 Sep 2021 13:00:19 GMT
>curl -I http://{IPofRemoteVM}:8080
HTTP/1.1 200
Accept-Ranges: none
Content-Type: application/json
Content-Length: 36121548
Date: Tue, 14 Sep 2021 13:00:23 GMT

Spring-Boot how to disable "Transfer-Encoding: chunked" in java

I have a problem with tomcat included with spring boot. i want to disable the chunked encoding or even using the HTTP 1.0 version as it doesn't use it. i don't have a java class for that i just want to change the properties.
below the part of the HTTP response header that i received with the chunked encoding
HTTP/1.1 200
Date: Thu, 26 Sep 2019 15:46:57 GMT
Content-Type: application/xml;charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive

How can I get Jetty to return an error response instead of assuming an HTTP/0.9 request?

A broken HTTP client sent some requests to our Jetty-based HTTP server with a newline in the URL. Jetty sees this as an HTTP/0.9 request, truncates the URL at the newline, ignores the request headers, and sends back a response with no headers or status line.
I believe this is mostly correct according to spec, although Jetty doesn't require CRLF and will happily do this for requests other than GET. But newer specs note that HTTP/0.9 requests mainly indicate confused clients. In our case, the client (and we) could have avoided some confused troubleshooting if an error message had been sent instead.
How can I get Jetty to return an error response to requests with a newline in the URL? I'm happy to use either Jetty-level configuration or webapp-level code.
First, support for HTTP/0.9 has been completely removed in Jetty 9.3+.
Lets see what the behavior is ...
Jetty Distribution 9.2.7.v20150116, running demo-base:
Normal HTTP/1.0 Request:
$ printf "GET / HTTP/1.0\r\n\r\n" | nc localhost 8080
HTTP/1.1 200 OK
Set-Cookie: visited=yes
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Accept-Ranges: bytes
Content-Type: text/html
Last-Modified: Sat, 17 Jan 2015 00:25:03 GMT
Content-Length: 2773
Server: Jetty(9.2.7.v20150116)
<html xmlns=\ "http://www.w3.org/1999/xhtml\" xml:lang=\"en\">
Got the headers there, looks like HTTP/1.0 response headers too.
Normal HTTP/1.1 Request:
$ printf "GET / HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n" | nc localhost 8080
HTTP/1.1 200 OK
Set-Cookie: visited=yes
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Accept-Ranges: bytes
Content-Type: text/html
Last-Modified: Sat, 17 Jan 2015 00:25:03 GMT
Content-Length: 2773
Connection: close
Server: Jetty(9.2.7.v20150116)
<html xmlns=\ "http://www.w3.org/1999/xhtml\" xml:lang=\"en\">
Looks normal as well.
Even includes the HTTP/1.1 specific headers.
Now lets try HTTP/1.0 with embedded CRLF:
$ printf "GET /\r\nHTTP/1.0\r\n\r\n" | nc localhost 8080
<html xmlns=\ "http://www.w3.org/1999/xhtml\" xml:lang=\"en\">
No response headers.
Why is this happening?
Well, there's no HTTP Version that Jetty can determine, so there's no valid set of headers it can respond with. So it responds with no headers. Which surprisingly is how HTTP spec prior to 1.0 behaved.
Now lets try Jetty Distribution 9.3.x, and the demo-base configuration with the same CRLF issue.
$ printf "GET /\r\nHTTP/1.0\r\n\r\n" | nc localhost 8080
HTTP/1.1 400 HTTP/0.9 not supported
Content-Length: 0
Connection: close
Server: Jetty(9.3.0-SNAPSHOT)
Now, in the modern era, with HTTP/2 just around the corner, this makes a lot more sense.
HttpServletRequest#getProtocol() will return an empty String for HTTP/0.9 requests in Jetty 8. Thus a simple filter can return a Bad Request response for such requests.
As the other answer indicates, HTTP/0.9 requests are no longer supported in recent versions of Jetty 9.

php - got no $_POST values with multipart/form-data

The question is easy. I am requesting:
POST /api/?user=auth HTTP/1.1 Content-Length: 437 Content-Type: multipart/form-data; boundary=tYhL_Uv6shSE9A9DHwvtJvXb0NPSLNMsdg; charset=UTF-8 Host: 192.168.0.10:8888 Connection: Keep-Alive User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.4)
--tYhL_Uv6shSE9A9DHwvtJvXb0NPSLNMsdg Content-Disposition: form-data; name="token"
KJjhyuJHYsadfU78
--tYhL_Uv6shSE9A9DHwvtJvXb0NPSLNMsdg Content-Disposition: form-data; name="api_login"
9053494481
--tYhL_Uv6shSE9A9DHwvtJvXb0NPSLNMsdg Content-Disposition: form-data; name="api_password"
8013468v30
--tYhL_Uv6shSE9A9DHwvtJvXb0NPSLNMsdg Content-Disposition: form-data; name="api_terms"
no
--tYhL_Uv6shSE9A9DHwvtJvXb0NPSLNMsdg--
and receive $_POST === array() in PHP.
PHP 5.3.3 (cli) (built: Dec 11 2013 03:29:57)
Copyright (c) 1997-2010 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies
with eAccelerator v1.0-dev, Copyright (c) 2004-2012 eAccelerator, by eAccelerator
And
Server version: Apache/2.2.15 (Unix)
Checked the server for rewrite redirects that can lose data - found none.
Please, help.
RESOLVED: I used apache library to send multipart request. It produced header:
Content-Type: multipart/form-data; boundary=tYhL_Uv6shSE9A9DHwvtJvXb0NPSLNMsdg; charset=UTF-8
When I remove encoding settings, it changed to:
Content-Type: multipart/form-data; boundary=tYhL_Uv6shSE9A9DHwvtJvXb0NPSLNMsdg
And now all works smooth.
That is a GET method!
Use:
$_GET
RESOLVED: I used apache library to send multipart request. It produced header:
Content-Type: multipart/form-data; boundary=tYhL_Uv6shSE9A9DHwvtJvXb0NPSLNMsdg; charset=UTF-8
When I remove encoding settings, it changed to:
Content-Type: multipart/form-data; boundary=tYhL_Uv6shSE9A9DHwvtJvXb0NPSLNMsdg
And now all works smooth.

Implementing If-Match HTTP Header in Spring

The ShallowEtagHeaderFilter which is part of Spring processes the If-None-Match header on an Http request. As part of the Http 1.1 spec this returns an Http status of 304 - Not Modified if the contents of the If-None-Match header sent on the request is the same as the Etag header. This is helpful for caching as it means that if the Etag is the same on the client and server then the contents will be identical.
This is fine.
However my question is this - does Spring have support for the If-Match header (again part of HTTP 1.1) rather than If-None-Match because as far as the docs go it looks like the ShallowEtagHeaderFilter only processes the If-None-Match header. I need the If-Match header to prevent simultaneous requests from overwriting the previous one. IE I only want the request to be processed if the Etags are the same and hence they have the latest version of the entity.
It doesn't look like the ShallowEtagHeaderFilter supports If-Match:
curl "Accept: application/json" -H 'If-Match: "somevalue"' -i http://localhost:8080/rest-sec/api/resources/1
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
ETag: "03cb37ca667706c68c0aad4cb04c3a211"
Content-Type: application/json;charset=UTF-8
Content-Length: 56
Date: Fri, 11 Jan 2013 14:58:40 GMT
I opened a JIRA issue to track this:
https://jira.springsource.org/browse/SPR-10164

Categories