Bug 21219 - Corrupted Message Body on interrupted GET
Summary: Corrupted Message Body on interrupted GET
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 4
Classification: Unclassified
Component: Connector:Coyote HTTP/1.1 (show other bugs)
Version: 4.1.18
Hardware: All All
: P3 enhancement with 1 vote (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-07-01 12:37 UTC by Stefan Eissing
Modified: 2004-11-16 19:05 UTC (History)
1 user (show)



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Stefan Eissing 2003-07-01 12:37:26 UTC
The servlet container tries to send a 500 Repsonse on Servlet/RuntimeExceptions
even though the response is already committed. This leads to currupted
message content, sometimes even without the client being able to notice
that something went wrong. 
Example: servlet dies with a RuntimeException while copying content to
the response.getOutputStream(). Only 1000 bytes are missing from the
ContentLength as specified in the response header. Then tomcat sends the
500 response on the same connection which is just long enough so that
the client is able to read the last 1000 bytes of the response. The
client will not notice that the response body is corrupted.

Solution: do not generate the 500 response when the original response is
already committed. Instead close the HTTP connection immediately so that
the client will know that the response is incomplete. Without closing
the HTTP connection, the client will hang trying to read the rest of the
response which will never come.
Comment 1 Remy Maucherat 2003-07-01 12:52:19 UTC
This won't be fixed (and is not a bug). You should add special handling in your
servlet. Please do not reopen this report.
Comment 2 Julian Reschke 2003-07-01 18:49:12 UTC
Can you be a bit more specific about what kind of special handling the servlet
is supposed to do in this case?
Comment 3 Remy Maucherat 2003-07-01 19:07:06 UTC
Well, you have a few options to play with:
- try to catch the runtime exception; it it happens that often, you should
handle it better
- extend the error report valve to suit your needs better
- don't set content-length (it doesn't improve performance on the server side,
as Coyote's chunking is extremely efficient)

Coyote considers that if less bytes are written, then there's a protocol error
(obviously). If too many bytes are written, the remaining bytes are eaten, but
there's no protocol error; maybe the error flag could be set in that cases (in
which case the connection would be closed at the end of the request processing).
Comment 4 Julian Reschke 2003-07-01 20:04:09 UTC
Well.

1) "handle it better" -- that's actually the issue -- how is a servlet supposed 
to handle this situation. Note that because the response may be already 
submitted, the only way to signal the client that there's an error condition 
seems to be force the container to close the connection. How do I do that?

2) That would be a change to Tomcat, right? (just clarifying)

3) That would be really an extreme measure. In particular, it would deny 
existing download clients the ability to show a useful progress indicator.
Comment 5 Julian Reschke 2003-07-04 07:19:53 UTC
I personally think that there's a big issue here, that needs a solution both in 
the spec and in Tomcat. If somebody thinks that there *is* a robust way to 
handle this situation, please elaborate.
Comment 6 Remy Maucherat 2003-07-04 07:51:01 UTC
Bugzilla is not a user support or a forum to ask for expert advice, but
exclusively meant to report confirmed (or at least issues you have a certain
level of confidence on) issues against Tomcat. You should use tomcat-user, or
other similar resources.
I have carefully evaluated this report, and do not think there is any fix needed
in Tomcat (other than the possibility I mentioned in my last comment). The
default behavior is acceptable for the vast majority of cases. If you want to
advocate a new, better, default behavior, feel free to post on tomcat -dev, but
you'll have to provide a patch, and convince people it is a useful change.
Please do not reopen the report.
Comment 7 william.barker 2003-07-04 08:22:42 UTC
Reopening to change status.
Comment 8 william.barker 2003-07-04 08:27:57 UTC
I disagree with Remy on this one.  This is different from how Apache/httpd 
handles bad requests, and I think that we should follow them when at all 
possible. I have posted a patch to TC 5.0.x that resolves it.  If it is not 
vetoed, then I'll back-port it to TC 4.1.25.  
Comment 9 Remy Maucherat 2003-07-04 11:50:49 UTC
Apache closes the connection on a 404 ?
If the answer is always yes, then -0 for your patch (so I'm not vetoing, but I'm
very close to that), otherwise, -1. I don't think we should always attempt to
match the HTTPd behavior when we can do something which matches the spec and is
more powerful. At least add a flag on the connector to allow configuring this
(just like there's a flag to disconnect after a certain amount of requests).

If the response has already been committed, I think your patch is ineffective,
so is why I think it is a bad idea overall. There's also the fact that you're
closing the connection without adding a Connection: close header (it's ok not
to, but still ...).

As I said in a previous comment, the only error we should detect in the HTTP
layer is if the amount of data written doesn't match the content length. Right
now, it is an error when less bytes are written, but if more are written, bytes
are swallowed and the error flag is not set (which of course, is not a protocol
violation).
Comment 10 Julian Reschke 2003-07-04 12:42:19 UTC
1) If the response is commited, *how* would you send out a connection: close?

2) Let me repeat what the issue is: the response is committed, but for some 
reason, the servlet isn't able to supply the advertised amount of bytes. In 
this case, there must be a way to fail the request. At this point, the only way 
to inform the client about the problem is to close the connection. Therefore, 
there should be a way for the servlet to reliably cause the servlet container 
to do this (for instance, by throwing a severe exception). Ultimately, the 
servlet spec should say something about this issue.
Comment 11 Julian Reschke 2003-07-18 16:31:57 UTC
I feel this bug should be reopened -- my understanding that only a change in 
Tomcat will enable servlets to behave properly.