Problems with always sending Content-Type, Expires and Pragma headers

2006-07-21 Thread J Ross Nicoll
I've been adapting my web application to handle the Range and If- 
Range headers. Problem is, if I send back a 206 response (partial  
content), sometimes I don't want to be sending Content-Type.  
Specifically, from RFC 2616, section 10.2.7:


"If the response is the result of an If-Range request that used a  
weak validator, the response MUST NOT include other entity-headers;  
this prevents inconsistencies between cached entity-bodies and  
updated headers."



Now; I may not entirely agree that this is a good idea, but that's  
what the spec says, and Content-Type is one of the "other entity- 
headers". However, if I don't specify a Content-Type, Tomcat (5.5.17)  
sets it to text/plain . So, I'm looking for Tomcat not to auto-set  
Content-Type in some cases. I'm saying this in e-mail, rather than  
submitting a bug report, because I'm not entirely sure of the best  
solution to this.


Now the simplest solution would, of course, be to not send Content- 
Type automatically on status code 206. However, that would break any  
applications that have come to depend on such behaviour. Also, I have  
a separate problem with Expires and Pragma always being sent on  
secure connections; while Expires can be overriden, Pragma should be  
excluded if not suitable.


The best solution I can think of to all these problems, would be to  
make headers to always be sent, a configuration option on the HTTP  
and AJP connectors. Thoughts?



-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Catching java.lang.Throwable

2006-08-12 Thread J Ross Nicoll
Found this recently: 
http://www.jroller.com/page/fate/?anchor=why_i_hate_tomcat


Most of it is ranting about parts of Tomcat I don't have any experience 
with working on, but it does mention Throwable being caught all over the 
place:


"The first issue is the fact that everywhere, Throwable is caught. Yes, 
even Error type exceptions are caught. Things that god and Sun never 
intended for applications to even try to handle, tomcat will (silently) 
catch and ignore. After all, when you run out of memory, best thing to 
do is keep going right?"


I'm currently working on some patches to reduce the number of places 
that catch Throwable, but felt a little bit of an explanation of what 
why catching Throwable is bad, might be in order. Trying not to make 
this sound too much like a lecture, and hope I don't irk people too much...


Looking at
"connectors/http11/src/java/org/apache/coyote/http11/Http11Processor.java", 
line 812:


try {
socket.setSoTimeout(soTimeout);
} catch (Throwable t) {
log.debug(sm.getString("http11processor.socket.timeout"), t);
error = true;
}

java.net.Socket.setSoTimeout(int) only lists java.net.SocketException as 
an exception it throws, so why are we catching everything? In 
particular, imagine the VM runs out of memory, the GC can't free any 
more up, and java.lang.OutOfMemoryError is thrown. This will happily 
ignore that error, only logging it if debugging level is enabled, and 
continue. While, sure, the alternative may be that Tomcat exits 
abruptly, but really is that any better to Tomcat grinding to an 
unpleasant halt? It's at least easy to tell a server has crashed, but 
unable to do anything because it's run out of memory is much trickier.


Further down the same file, line 838:

// Parsing the request header
try {
if( !disableUploadTimeout && keptAlive && soTimeout > 0 ) {
socket.setSoTimeout(soTimeout);
}
inputBuffer.parseRequestLine();
request.setStartTime(System.currentTimeMillis());
thrA.setParam( threadPool, request.requestURI() );
keptAlive = true;
if (!disableUploadTimeout) {
socket.setSoTimeout(timeout);
}
inputBuffer.parseHeaders();
} catch (IOException e) {
error = true;
break;
} catch (Throwable t) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("http11processor.header.parse"), t);
}
// 400 - Bad Request
response.setStatus(400);
error = true;
}

I'm fairly certain it should be returning 500, not 400, but that's not 
the point. Here, catching Throwable is correct; you do not want an error 
to leave the connection in an indeterminate state. However, once the 
error status has been sent, it should be thrown upwards again.


It might make sense to catch specific Error subclasses higher up, if 
they can be dealt with (for example, catch OutOfMemoryError, clear out 
caches, and then call the GC to try fixing the situation), but catching 
Throwable throughout the code is dangerous. Particularly, some of the 
errors, for example ThreadDeath, need to propagate upwards to ensure 
correct operation of the VM!


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]