-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Review content-length check in ServletChannel #11325
Comments
@gregw is this check necessary? I vaguely remember it is required by the Servlet spec? We either need a way to count the bytes precisely before the check is performed, or we need to do the check after the aggregation buffer is flushed. Thoughts? |
The servlet spec requires that we commit the response as soon as precisely the number of bytes written matches any content-length set. I don't recall that we need to actively police too few bytes written and it should be impossible to write too many. Both of these will be caught by core. |
@sbordet Is this an actual bug/issue? Can you provide and example of what you mean by "too early" The requirement to commit as soon as a precise number of bytes have been written is only from the servlet spec and only relates to code that does response.setContentLength and then writes to the outputstream or writer. The DefaultServlet is free to write its content as it wants, and bypassing HttpOutput will result in the commit after bytes written behaviour as expected. Note also that lots of thinks might change the actual content size (eg GzipHandler). From the servlet spec point of view, these do not exist. This if the app as said the content length is 1000, we need to allow it to write 1000 bytes and then close the response for it, regardless of how many bytes are actually in the real response. So there are two kinds of checks: one for the servlet API, which needs to be done high in the stack (around HttpOutput) to trigger closes; another low in the stack to ensure we are sending valid HTTP responses. |
Currently we are counting bytes written in 3 places:
We do need to rationalize this and count only before/after compression |
Fix #11325 by: + removing content-length tracking from ServletContextResponse + adding a setContentLengthSet field to HttpOutput
Fix #11325 by: + removing content-length tracking from ServletContextResponse + adding a setContentLengthSet field to HttpOutput
Fixed flaky tests due to thread local context left set.
Fix #11325 by: + removing content-length tracking from ServletContextResponse + adding a setContentLengthSet field to HttpOutput + added HttpOutputTest for EE10/EE11
Jetty version(s)
12+
Jetty Environment
ee10, possibly others too
Description
ServletChannel.handle()
in caseCOMPLETE
performs a check on the content-length, to see if it the actual bytes written match the value of the header.Unfortunately, this check is performed too early in case of buffered content if looking at the bytes written to the
ServletContextResponse
(they are written to theHttpOutput
, but not yet to theServletContextResponse
).However, we cannot look at the bytes written to
HttpOutput
, because currently the welcome files are written bypassing it, so content-length the check would fail.This could be solved by always wrapping the Servlet response in
DefaultServlet
, so it never bypassesHttpOutput
so the count is always correct.Lastly, the solution needs to take into account the possibility of gzip being performed before or after the
ContextHandler
.The text was updated successfully, but these errors were encountered: