Spring-Boot how to disable "Transfer-Encoding: chunked" in java - 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

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

Gzip compression not working in my project with Spring boot 1.5.10.RELEASE

I am using Spring Boot 1.5.10.RELEASE version. Gzip compress not working.
http://localhost:9000 --> http://localhost:8080/api/..
Angularjs & rest api on different Port. Enabled CrossOrigin to accept request from angularjs ui.
Using embedded tomcat server to deploy spring boot application.
Not using http2 property i.e. server.http2.enabled=true
Angualrjs calls rest api. Following is $http service
$http({
method: method,
url: url,
params: params,
data: body,
headers: {
Authorization: token,
"Content-type": 'application/json'
}
});
Rest api response size Approx 25 MB so I want to compress response.
I have added well known property in application.properties to apply gzip compression.
Spring boot 1.5.10 Supported properties
# Enable response compression
server.compression.enabled=true
# The comma-separated list of mime types that should be compressed
server.compression.mime-types=text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json
# Compress the response only if the response size is at least 1KB
server.compression.min-response-size=1024
I have observed network tab and no observed Content-Encoding: gzip in response header.
Request
Request URL: http://localhost:9081/employee
Request Method: GET
Status Code: 200
Remote Address: [::1]:9081
Referrer Policy: no-referrer-when-downgrade
Response Header
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:7000
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Type: application/json;charset=UTF-8
Date: Sun, 28 Jun 2020 18:15:17 GMT
Expires: 0
Pragma: no-cache
Set-Cookie: JSESSIONID=6E7C07874D0329E18A0C07E5E303F005; Path=/; HttpOnly
Transfer-Encoding: chunked
Vary: Origin
X-Application-Context: application
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Request Header
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Authorization: Bearer eyJhbGciOiJIUzINiJ9.eyJyb2xlIjiU0VDVE9SSEVBRCIsImxldmVsRG93biI6IkVENzA0MTI7TU04MzcyNDtKTDgzNTwO0RNNDAwNzE7Skc3MzA0NjtFQzM0NjEzO05OMTY5Nzk7QUs2MDYzNztTVDE4NTg4O0FTMjczNTE7Q0I4MTg3OTtWQTc4MTk5O0NNOTM3MDA7QVkyMzYzNztKUzcwMDY4O0NCMTc2NzE7TksyMTU2MDtMUzg4OTg0O0FQNTg3MDg7VFcyjk0NTtKSzI1Nzc3O01TNDk5MjE7SkI4OTcyOTtNSDAyMTI3O01CMTUwODk7SU0xMjgwODtNQzcxOTc2O1JSMjAzMDI7TFM1ODk4MiIsImxldmVsVXAiOm51bGwsImRlbGVnYXRlZCI6bnVsbCwic29lSWQiOiJTUjQ0MTg1I0.*************
Cache-Control: no-cache
Connection: keep-alive
Content-type: application/json
Host: localhost:9081
Origin: http://localhost:7000
Pragma: no-cache
Referer: http://localhost:7000/build/standalone.html
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36
I am not getting following expected headers in response header
Content-Encoding: gzip
Vary: Accept-Encoding
Any changes require at client /server side ?
---[Edit-1] -------------
Tried gzip in individual project which worked but not worked in my project.
Following is response header when invoke rest api from browser
Content-Encoding: gzip
Content-Type: application/json;charset=UTF-8
Date: Sun, 28 Jun 2020 18:12:29 GMT
Transfer-Encoding: chunked
Vary: Accept-Encoding
-----[Edit-2]-----Ziplet----
Using ziplet dependency I am able to compress response, but I want to use spring boot gzip compression.
Response header - when used Ziplet
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:7000
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Encoding: gzip
Content-Type: application/json;charset=UTF-8
Date: Mon, 06 Jul 2020 18:31:07 GMT
Expires: 0
Pragma: no-cache
Set-Cookie: JSESSIONID=8465D2E81A1A9CE146255B6C545FBE30; Path=/; HttpOnly
Transfer-Encoding: chunked
Vary: Accept-Encoding
Vary: Origin
X-Application-Context: application
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
When used ziplet - I can see
CompressingFilter : CompressingFilter has initialized
When using Spring boot gzip compression not observed anything where I can assume gzip compression enabled.
Any property to debug spring boot gzip compression with embeded tomcat ?
like logging.level.org.eclipse.jetty.server.handler.gzip=TRACE
How can i verify server.compression.enabled ?
Any changes require at client /server side in my project?
Thanks in advance.
As your question, you are using Spring Boot 1.5.10.RELEASE.
For that version of the framework, the class TomcatEmbeddedServletContainerFactory is responsible for starting the embedded Tomcat container.
The source code of that class and version can be found here:
https://github.com/spring-projects/spring-boot/blob/v1.5.10.RELEASE/spring-boot/src/main/java/org/springframework/boot/context/embedded/tomcat/TomcatEmbeddedServletContainerFactory.java
In this class, you can find the method customizeCompression:
private void customizeCompression(Connector connector) {
ProtocolHandler handler = connector.getProtocolHandler();
if (handler instanceof AbstractHttp11Protocol) {
AbstractHttp11Protocol<?> protocol = (AbstractHttp11Protocol<?>) handler;
Compression compression = getCompression();
protocol.setCompression("on");
protocol.setCompressionMinSize(compression.getMinResponseSize());
configureCompressibleMimeTypes(protocol, compression);
if (getCompression().getExcludedUserAgents() != null) {
protocol.setNoCompressionUserAgents(
StringUtils.arrayToCommaDelimitedString(
getCompression().getExcludedUserAgents()));
}
}
}
Try setting a breakpoint on this method and debug your application to see if compression is actually enabled.
If not, it is very likely that there is some kind of wrong configuration in your project.
If it works, it indicates that your configuration is correct and that the problem is different.
If this is the case, before looking at anything else, it might be appropriate to try another server, such as Jetty or Undertow, which also support this compression feature, and see if everything works correctly there.
For instance, to configure Undertow instead of Tomcat you can use the following:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
You can try to configure Tomcat compression programmatically as well; see matsev's answer in this stackoverflow question:
Using GZIP compression with Spring Boot/MVC/JavaConfig with RESTful
You have to enable http2 support in your spring boot properties
server.http2.enabled=true
And then try

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

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...

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.

Does the Single Sign On Paradigm respects the HTTP protocol rules?

We are using the CAS server for a JAVA web application.
The authentication system is as follows:
A user tries to access a resource (1) on the system
It get redirects (302 Found)
The User Enters the username password
The Server answers with a cookie and redirects to the original page (1)
I am debated on the fact that this interaction respects the HTTP protocol.
If I do not have the authorization to access a resource
shouldn't the system answer with a 401 Unauthorized or even better a 407 Proxy Authentication Required ?
And the Authorization Resource, couldn't be instead of a Cookie string a full SSL-Level authorization key ?
Added:
Header dump using curl -L -D
HTTP/1.1 301 Moved Permanently
Server: nginx/0.8.54
Date: Sat, 10 Dec 2011 02:07:55 GMT
Content-Type: text/html
Content-Length: 185
Connection: keep-alive
Location: https://server.com/service/
HTTP/1.1 302 Found
Server: nginx/0.8.54
Date: Sat, 10 Dec 2011 02:07:55 GMT
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: no-store, max-age=0, must-revalidate
Expires: Thu, 01-Jan-1970 00:00:00 GMT
Set-Cookie: JSESSIONID=q7rjikj4spvd1fxaowjl9XXX
Location: https://server.com/login/
HTTP/1.1 200 OK
Server: nginx/0.8.54
Date: Sat, 10 Dec 2011 02:07:55 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.3.2
Content-Length: 6650
You're right - the SSO system in your examples is really at a different level than the HTTP protocol itself. If the application returned a 401 then the browser itself will likely handle the authentication (e.g.: prompt the user for username/password, then send the next request with this base-64 encoded in the HTTP Authorization header). In the case of HTTP Basic authentication the username & password would then be sent with every request to your system. You may do authentication with Kerberos or NTLM, in which case the authentication could be transparent if the user is already logged into the network.
That said - many SSO systems take the approach of redirecting the user to a login HTML form, and then maintaining session state with a cookie. One of the main benefits is you have more control over the look & feel of the login interface. With the SSO system having a session cookie it can take ownership of maintaining the state in its own (likely proprietary) way.

Categories