Hi,
I did some research on BZ 44995 and BZ 45092 and stumbled into the
following observation:
It seems that httpd 2.0 and 2.2 require a non empty reason phrase in the
status line. RFC 2616 allows an empty reason phrase:
6.1 Status-Line
Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
6.1.1 Status Code and Reason Phrase
Reason-Phrase = *<TEXT, excluding CR, LF>
Because of the star (*) I read this as "empty reason phrase is allowed".
This inconsistency showed up in the above issues, because Tomcat
returned an empty reason phrase for custom HTTP status codes and mod_jk
passed the empty reason phrase along to httpd. mod_proxy_ajp seems to
behave in the same way. This resulted in httpd returning a 500 status
code instead of the custom status code, because any status line with an
empty reason phrase is first replaced by an empty one, and then the
empty one is replaced by the default one. Since there is no default
status line for custom http status codes (like 450), we use the status
500 line. The request is then returned to the client with status 500 and
logged in the access log with the custom status code.
Do you agree, that empty reason phrases should be allowed?
If so, the below code fragments should be reviewed. I could provide the
(trivial) patch.
Furthermore there is a second, related problem (for 2.x *and* 1.3):
error pages use the status line as a title. If the line has an empty
reason phrase *and* uses a custom http status code, error pages will
show the title for status code 500.
I'll add the info to the BZ issues, if there is consensus, that empty
reason phrases should be allowed.
Apache 2.0
==========
/httpd/httpd/branches/2.0.x/modules/http/http_protocol.c
--------------------------------------------------------
1174 /* Confirm that the status line is well-formed and matches r->status.
1175 * Otherwise, a filter may have negated the status line set by a
1176 * handler.
1177 * Zap r->status_line if bad.
1178 */
1179 static void validate_status_line(request_rec *r)
1180 {
1181 char *end;
1182
1183 if (r->status_line
1184 && (strlen(r->status_line) <= 4
!! Why 4 instead of 3? "nnnSPACE" should be allowed.
1185 || apr_strtoi64(r->status_line, &end, 10) != r->status
1186 || *end != ' '
1187 || (end - 3) != r->status_line)) {
1188 r->status_line = NULL;
1189 }
1190 }
Apache 2.2
==========
/httpd/httpd/branches/2.2.x/modules/http/http_filters.c
-------------------------------------------------------
797 /* Confirm that the status line is well-formed and matches r->status.
798 * If they don't match, a filter may have negated the status line
set by a
799 * handler.
800 * Zap r->status_line if bad.
801 */
802 static void validate_status_line(request_rec *r)
803 {
804 char *end;
805
806 if (r->status_line
807 && (strlen(r->status_line) <= 4
!! Why 4 instead of 3? "nnnSPACE" should be allowed.
808 || apr_strtoi64(r->status_line, &end, 10) != r->status
809 || *end != ' '
810 || (end - 3) != r->status_line)) {
811 r->status_line = NULL;
812 }
813 }
trunk
=====
/httpd/httpd/trunk/modules/http/http_filters.c
796 /* Confirm that the status line is well-formed and matches r->status.
797 * If they don't match, a filter may have negated the status line
set by a
798 * handler.
799 * Zap r->status_line if bad.
800 */
801 static void validate_status_line(request_rec *r)
802 {
803 char *end;
804
805 if (r->status_line
806 && (strlen(r->status_line) <= 4
807 || apr_strtoi64(r->status_line, &end, 10) != r->status
808 || *end != ' '
809 || (end - 3) != r->status_line)) {
810 r->status_line = NULL;
811 }
812 }
Regards,
Rainer