Issue with Jetty on POST/PUT/PATCH with empty content (consider disabling gzip all the time)
When a HTTP request has an empty content (no payload) for a POST/PUT/PATCH, a Jetty server fails with the following stack for a client request created by this API with the default parameters:
org.eclipse.jetty.http.BadMessageException: 501: Unsupported Content-Encoding
at org.eclipse.jetty.server.Request.extractContentParameters(Request.java:517)
at org.eclipse.jetty.server.Request.getParameters(Request.java:430)
at org.eclipse.jetty.server.Request.getParameter(Request.java:1059)
It fails to analyse parameters because the content-size is not set and the headers are not consistent. Here are the default headers:
Accept-Encoding: gzip
Authorization: Bearer ya29.a0AfH6SMDK...
User-Agent: Integration Tests Google-API-Java-Client/1.30.9 Google-HTTP-Java-Client/1.35.0 (gzip)
x-goog-api-client: gl-java/11.0.7 gdcl/1.30.9 linux/5.3.0
Content-Encoding: gzip
On a previous version of this lib, the Content-Size was set to 27, which is the compression of the empty content.
When the compression is disabled (.setDisableGZipContent(true)), the headers are ok and it works well with Jetty:
Accept-Encoding: gzip
Authorization: Bearer ya29.a0AfH6SMDK...
User-Agent: Integration Tests Google-API-Java-Client/1.30.9 Google-HTTP-Java-Client/1.35.0 (gzip)
x-goog-api-client: gl-java/11.0.7 gdcl/1.30.9 linux/5.3.0
Content-Length: 0
For this kind of request in particular, with empty content in general (when the content size can be determined), the field disableGZipContent in the class AbstractGoogleClientRequest should be ignored and the compression always disabled. This will avoid some tricky errors with the default parameters of an AbstractGoogleClientRequest and avoid unnecessary compression.
In com.google.api.client.googleapis.services.AbstractGoogleClientRequest, around line 426, there is a few lines handling this kind of request
// custom methods may use POST with no content but require a Content-Length header
if (httpContent == null && (requestMethod.equals(HttpMethods.POST)
|| requestMethod.equals(HttpMethods.PUT) || requestMethod.equals(HttpMethods.PATCH))) {
httpRequest.setContent(new EmptyContent());
}
You may force the disabling of the compression just after to really have the Content-Length header.
More recent Jetty versions (the one currently used by Google App Engine Standard for Java 8) will fail with a slightly different error (415 instead of 501)
org.eclipse.jetty.http.BadMessageException: 415: Unsupported Content-Encoding at org.eclipse.jetty.server.Request.extractContentParameters(Request.java:528) at org.eclipse.jetty.server.Request.getParameters(Request.java:435) at org.eclipse.jetty.server.Request.getParameter(Request.java:1075)
Any chance this could be fixed someday, as this is clearly a regression?