Bug 45026

Summary: Custom HTTP-Error codes get remapped to 500er codes
Product: Tomcat Connectors Reporter: Jan Schulte <jan.schulte>
Component: CommonAssignee: Tomcat Developers Mailing List <dev>
Severity: normal CC: jens.scheffler
Priority: P2    
Version: unspecified   
Target Milestone: ---   
Hardware: PC   
OS: Windows XP   

Description Jan Schulte 2008-05-18 04:16:12 UTC
We use Apache 2.2.8 with mod_JK 1.2.26 as a load-balancer for a Tomcat 5.5 cluster.
We use Custom HTTP-Error codes like 450 for authentication-purposes. Those
codes get remapped to 500.
The Error-Code 450 is in the RFC2616 described as valid return code so this is
a bug.

The custom error-codes worked fine in Apache 1.3.41 with MOD_JK/1.2.25.

You can easily reproduce this bug by writing a simple jsp-page with the following
Comment 1 Mark Thomas 2008-05-18 05:02:26 UTC
With the same version of Tomcat (trunk) and a slightly older mod_jk (1.2.24) this appears to be a difference between httpd 1.3.x and 2.2.x

I've has a quick look in RFC 2616 and I didn't find anything relating to custom status codes. Can you provide a reference to the section of RFC2616 to which you are referring.

I need to take a look at the httpd docs.
Comment 2 Rainer Jung 2008-05-18 08:43:09 UTC
If necessary, the httpd part of this issue should be discussed in its predecessor BZ 44495 ( https://issues.apache.org/bugzilla/show_bug.cgi?id=44995 ).
Comment 3 Mark Thomas 2008-05-18 09:46:34 UTC
Thanks Rainer. It would of been helpful if that had been included in the original report.

I've taken a look at mod_jk and it seems to be complaining about a lack of a body. I'm not sure if this is a Tomcat or a mod_jk issue at the minute. Need to do more testing.
Comment 4 Mark Thomas 2008-05-18 11:27:59 UTC
Rainer - this might be quicker for you to track down. The following patch ensures the correct status is returned but the body generated by Tomcat is disappearing somewhere (I suspect inside mod_jk).

Index: java/org/apache/jk/common/JkInputStream.java
--- java/org/apache/jk/common/JkInputStream.java	(revision 657140)
+++ java/org/apache/jk/common/JkInputStream.java	(working copy)
@@ -278,6 +278,10 @@
         } else {
             message = message.replace('\n', ' ').replace('\r', ' ');
+        if (message == null) {
+            // mod_jk + httpd 2.x fails with a null status message - bug 45026
+            message = Integer.toString(res.getStatus());
+        }
         tempMB.setString( message );
         c2b.convert( tempMB );
Comment 5 Rainer Jung 2008-05-20 06:01:31 UTC
That helped a lot. Indeed it seems httpd 2.x forces a status line to contain a non empty reason phrase, although RFC 2616 seems to allow empty ones. I posted to httpd-dev about that.

I would say your patch looks good, because having a trivial one looks better then none and it fixes the problem independent of any httpd fix.

Depending on the httpd discussion, I'll see, if we add the same check to mod_jk as well, to fix the problem for older TC and httpd.
Comment 6 Rainer Jung 2008-05-20 07:24:30 UTC
See: http://marc.info/?t=121128830700002&r=1&w=2
Comment 7 Rainer Jung 2008-05-26 04:54:52 UTC
A fix will be included in mod_jk version 1.2.27.

Although the root problem lies within Apache httpd 2.x, we are able to work around it. We will add "Unknown Reason" as a reason phrase in case we receive an http status with empty reason phrase from the backend (as is likely for custom http stati; unfortunately the servlet spec has no method for setting a reason phrase).

A similar approach will be taken for Tomcat, to not return an empty reason phrase.

I guess, the httpd people will also make httpd more tolerant for empty reason phrases.
Comment 8 Jens Scheffler 2008-06-11 06:30:51 UTC
Thanks for the information - while 1.2.27 of the plugin is still not fully released and also the httpd will take a moment to get this implemented we managed to change our code to always include a reason phrase - the servlet spec allows to send one or leave it out. If a correct reason is provided, it is working out fine.

when the code...
response.setStatus(int) or
...is used, the problem is showing up and HTTP 500 is returned to user.

If we use the both methods...
response.setStatus(int, String) or
response.sendError(int, String)
...and the String is NOT NULL, then the resulting HTTP response code is correct.

Thanks & Best Regards,

Comment 9 Rainer Jung 2009-04-06 15:14:57 UTC
A fix has also been applied to TC 6.0 (r762499) and TC 5.5 (r762510) to become part of 6.0.20 and 5.5.28. So updating either one of mod_jk or Tomcat does already solve the problem.