Open ghost opened 1 year ago
Also note that Jetty's GzipHandler can uncompress request body content, you don't need to add a hack to do it yourself.
You just need to specify an inflate buffer size on the GzipHandler for it to start to be used. (set it to 8192 and you'll be good)
GzipHandler gzipHandler = new GzipHandler();
gzipHandler.setInflateBufferSize(8192); // enable request body inflation (aka decompression)
But anything you want me to try/test I will try to fit in.
@silviobierman I don't think we have found a smoking gun for these problems, but we have found a number of issues that can definitely be improved. We will get fixes for those merged in the next few days and then ask you to try again.
Also note that Jetty's GzipHandler can uncompress request body content, you don't need to add a hack to do it yourself.
@joakime I think the issue is that the request is multi-part with a single part that is a compressed file. So the jetty GzipHandler will not see it, as we do not decompress within the parts.
Also note that Jetty's GzipHandler can uncompress request body content, you don't need to add a hack to do it yourself.
@joakime I think the issue is that the request is multi-part with a single part that is a compressed file. So the jetty GzipHandler will not see it, as we do not decompress within the parts.
A prior comment does not indicate multipart is in use - https://github.com/jetty/jetty.project/issues/10513#issuecomment-1837594354
My understanding is that the zipped content can be uploaded either by multipart form content, or as a "plain ZIP upload". However, the problem "described is with a JavaScript FormData originated FORM POST with a single part that contains ZIP content. No unzipping by Jetty" So the problematic case is when our GzipHandler cannot be used.
The errors seen suggest some corruption of the part, which could be the single byte read issue that @lorban is fixing. The hangs could be the fact that we are not resetting the h2 stream with a NO_ERROR reset, so end up waiting for content that will not be sent.
@joakime @gregw : The ZIP-archives are generated by the reverse process in the GET-handler. All tests I have done revealed that reading all its entries fully in the POST-handler left 0 bytes at the end of the request/part. So either as the sole content of a POST or inside a multi-part request with a ZIP-archive part the application processes the ZIP-archive fully reading all bytes of all entries.
And this is not about transfer encoding with gzip but simply content types that happen to be (sometimes nested meaning ZIP inside ZIP) ZIP-archives which are processed by the application in several different ways depending on context and content.
Correct me if I am wrong but I was under the assumption that it is the containers responsibility to keep up the notion of separate independent requests meaning it will drop unprocessed bytes after something like a synchronous doPost returns or throws and not let them leak through into subsequent requests.
There is a common trait in all these cases: the server needs considerable time to process the data and does not buffer it to finish the request early. The back pressure results in a client (in my ZIP-archive test case being the browser) waiting sometimes several minutes up to even 45-60 minutes in extreme cases for the server to accept all the data. My current test case is a 503Mb ZIP that takes about a minute to process on localhost which is my laptop with an NVME SSD. Practical cases of restoring full backups go upto 60-70Gb ZIP-archives with a curl client (no multipart) which may take close to an hour.
The CSV feeds that went wrong for the Expect:100-continue clients (ie. .NET clients) cases take much less time in the range of 10-30 seconds.
I think we are looking at several problems here. We will soon have some new images for you to test. stand by...
Jetty version(s) 12.0.1
Jetty Environment ee10 / http/2
Java version/vendor
(use: java -version)
OpenJDK Runtime Environment (Red_Hat-21.0.0.0.35-1.rolling.fc38) (build 21+35) OpenJDK 64-Bit Server VM (Red_Hat-21.0.0.0.35-1.rolling.fc38) (build 21+35, mixed mode, sharing)OS type/version Fedora 38 Workstation
Description This application sets up an embedded Jetty 12.0.1 instance with one servlet class TestServlet1. The doPost method simply tries to read-and-discard the content of the body before sending a short response. Posting a sufficiently large file to the application will result in a lockup. The curl client will block trying to send more data while the application blocks trying to read. The point where th size of the POST body is printed to stderr is then never reached.
A slight modification of the code makes it use TestServlet2 with a doPost that processes the input expecting a ZIP-formatted body by reading and discarding entries and printing the name:size of each entry to stderr. Posting a sufficiently large ZIP file to it shows that initial entries are processed corrrectly then it locks up the same way as with TestServlet1.
Small POST requests seem to work without issues. GET requests seem to work fine also and our application ported from Jetty 11 to Jetty 12 works mostly fine except for large POST requests.
How to reproduce? See the above description. I am sorry that this is Scala code instead of Java. I currently have no Java development environment setup.
Compile/runtime dependencies specified in build.sbt, some of which redundant for the test code
Scala code