I came across the question if we should not reject HTTP protocols >= 2.0 in the request line when we parse it
in ap_parse_request_line.
This does not affect mod_http2 if loaded as HTTP/2.0 connections itself are not parsed via ap_parse_request_line
and sending a
GET /something HTTP/2.0
as request line is not a valid way to start a HTTP 2.0 connection and I doubt that it will be for future major versions.
A possible patch could look like the following (which rejects such requests with a HTTP_VERSION_NOT_SUPPORTED status code):
Index: server/protocol.c
===================================================================
--- server/protocol.c (revision 1878470)
+++ server/protocol.c (working copy)
@@ -748,7 +748,7 @@ AP_DECLARE(int) ap_parse_request_line(request_rec
enum {
rrl_none, rrl_badmethod, rrl_badwhitespace, rrl_excesswhitespace,
rrl_missinguri, rrl_baduri, rrl_badprotocol, rrl_trailingtext,
- rrl_badmethod09, rrl_reject09
+ rrl_badmethod09, rrl_reject09, rrl_versionnotsupported
} deferred_error = rrl_none;
apr_size_t len = 0;
char *uri, *ll;
@@ -897,6 +897,11 @@ rrl_done:
r->proto_num = HTTP_VERSION(0, 9);
}
+ if (strict && deferred_error == rrl_none
+ && r->proto_num >= HTTP_VERSION(2, 0)) {
+ deferred_error = rrl_versionnotsupported;
+ }
+
/* Determine the method_number and parse the uri prior to invoking error
* handling, such that these fields are available for substitution
*/
@@ -918,6 +923,7 @@ rrl_done:
* we can safely resume any deferred error reporting
*/
if (deferred_error != rrl_none) {
+ r->status = HTTP_BAD_REQUEST;
if (deferred_error == rrl_badmethod)
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03445)
"HTTP Request Line; Invalid method token: '%.*s'",
@@ -954,7 +960,13 @@ rrl_done:
"HTTP Request Line; Unrecognized protocol '%.*s' "
"(perhaps whitespace was injected?)",
field_name_len(r->protocol), r->protocol);
- r->status = HTTP_BAD_REQUEST;
+ else if (deferred_error == rrl_versionnotsupported) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO()
+ "HTTP Request Line; Protocol '%.*s' >= HTTP/2.0 not"
+ " supported", field_name_len(r->protocol),
+ r->protocol);
+ r->status = HTTP_VERSION_NOT_SUPPORTED;
+ }
goto rrl_failed;
}
Regards
Rüdiger
in ap_parse_request_line.
This does not affect mod_http2 if loaded as HTTP/2.0 connections itself are not parsed via ap_parse_request_line
and sending a
GET /something HTTP/2.0
as request line is not a valid way to start a HTTP 2.0 connection and I doubt that it will be for future major versions.
A possible patch could look like the following (which rejects such requests with a HTTP_VERSION_NOT_SUPPORTED status code):
Index: server/protocol.c
===================================================================
--- server/protocol.c (revision 1878470)
+++ server/protocol.c (working copy)
@@ -748,7 +748,7 @@ AP_DECLARE(int) ap_parse_request_line(request_rec
enum {
rrl_none, rrl_badmethod, rrl_badwhitespace, rrl_excesswhitespace,
rrl_missinguri, rrl_baduri, rrl_badprotocol, rrl_trailingtext,
- rrl_badmethod09, rrl_reject09
+ rrl_badmethod09, rrl_reject09, rrl_versionnotsupported
} deferred_error = rrl_none;
apr_size_t len = 0;
char *uri, *ll;
@@ -897,6 +897,11 @@ rrl_done:
r->proto_num = HTTP_VERSION(0, 9);
}
+ if (strict && deferred_error == rrl_none
+ && r->proto_num >= HTTP_VERSION(2, 0)) {
+ deferred_error = rrl_versionnotsupported;
+ }
+
/* Determine the method_number and parse the uri prior to invoking error
* handling, such that these fields are available for substitution
*/
@@ -918,6 +923,7 @@ rrl_done:
* we can safely resume any deferred error reporting
*/
if (deferred_error != rrl_none) {
+ r->status = HTTP_BAD_REQUEST;
if (deferred_error == rrl_badmethod)
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03445)
"HTTP Request Line; Invalid method token: '%.*s'",
@@ -954,7 +960,13 @@ rrl_done:
"HTTP Request Line; Unrecognized protocol '%.*s' "
"(perhaps whitespace was injected?)",
field_name_len(r->protocol), r->protocol);
- r->status = HTTP_BAD_REQUEST;
+ else if (deferred_error == rrl_versionnotsupported) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO()
+ "HTTP Request Line; Protocol '%.*s' >= HTTP/2.0 not"
+ " supported", field_name_len(r->protocol),
+ r->protocol);
+ r->status = HTTP_VERSION_NOT_SUPPORTED;
+ }
goto rrl_failed;
}
Regards
Rüdiger