You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Jim Jagielski <ji...@jaguNET.com> on 2002/07/08 16:49:29 UTC
ProtocolReqCheck directive patch
This implements the runtime setting for a "strict" checking of the
Protocol field in requests for 1.3. Might be useful for 2.0, if we
decide that as well.
Index: src/include/http_conf_globals.h
===================================================================
RCS file: /home/cvs/apache-1.3/src/include/http_conf_globals.h,v
retrieving revision 1.48
diff -u -r1.48 http_conf_globals.h
--- src/include/http_conf_globals.h 13 Mar 2002 21:05:29 -0000 1.48
+++ src/include/http_conf_globals.h 8 Jul 2002 14:43:40 -0000
@@ -103,6 +103,8 @@
extern enum server_token_type ap_server_tokens;
+extern int ap_protocol_req_check;
+
/* Trying to allocate these in the config pool gets us into some *nasty*
* chicken-and-egg problems in http_main.c --- where do you stick them
* when pconf gets cleared? Better to just allocate a little space
Index: src/main/http_core.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_core.c,v
retrieving revision 1.313
diff -u -r1.313 http_core.c
--- src/main/http_core.c 18 Jun 2002 00:59:57 -0000 1.313
+++ src/main/http_core.c 8 Jul 2002 14:43:42 -0000
@@ -2778,6 +2778,18 @@
}
#endif /*_OSD_POSIX*/
+static const char *set_protocol_req_check(cmd_parms *cmd,
+ core_dir_config *d, int arg)
+{
+ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+ if (err != NULL) {
+ return err;
+ }
+
+ ap_protocol_req_check = arg != 0;
+ return NULL;
+}
+
/*
* Handle a request to include the server's OS platform in the Server
* response header field (the ServerTokens directive). Unfortunately
@@ -2785,7 +2797,6 @@
* http_main so it can insert the information in the right place in the
* string.
*/
-
static const char *set_serv_tokens(cmd_parms *cmd, void *dummy, char *arg)
{
const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
@@ -3411,6 +3422,8 @@
(void*)XtOffsetOf(core_dir_config, limit_req_body),
OR_ALL, TAKE1,
"Limit (in bytes) on maximum size of request message body" },
+{ "ProtocolReqCheck", set_protocol_req_check, NULL, RSRC_CONF, FLAG,
+ "Enable strict checking of Protocol type in requests" },
{ "AcceptMutex", set_accept_mutex, NULL, RSRC_CONF, TAKE1,
"Serialized Accept Mutex; the methods "
#ifdef HAVE_USLOCK_SERIALIZED_ACCEPT
Index: src/main/http_main.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_main.c,v
retrieving revision 1.587
diff -u -r1.587 http_main.c
--- src/main/http_main.c 18 Jun 2002 23:34:31 -0000 1.587
+++ src/main/http_main.c 8 Jul 2002 14:43:51 -0000
@@ -398,6 +398,9 @@
/* Global, alas, so http_core can talk to us */
enum server_token_type ap_server_tokens = SrvTk_FULL;
+/* Also global, for http_core and http_protocol */
+int ap_protocol_req_check = 1;
+
/*
* This routine is called when the pconf pool is vacuumed. It resets the
* server version string to a known value and [re]enables modifications
Index: src/main/http_protocol.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/main/http_protocol.c,v
retrieving revision 1.322
diff -u -r1.322 http_protocol.c
--- src/main/http_protocol.c 26 Jun 2002 18:34:00 -0000 1.322
+++ src/main/http_protocol.c 8 Jul 2002 14:43:53 -0000
@@ -991,7 +991,9 @@
const char *uri;
conn_rec *conn = r->connection;
unsigned int major = 1, minor = 0; /* Assume HTTP/1.0 if non-"HTTP" protocol */
- int len, n = 0;
+ int len = 0;
+ int valid_protocol = 1;
+ char *kruft;
/* Read past empty lines until we get a real request line,
* a read error, the connection closes (EOF), or we timeout.
@@ -1053,26 +1055,41 @@
r->assbackwards = (ll[0] == '\0');
r->protocol = ap_pstrdup(r->pool, ll[0] ? ll : "HTTP/0.9");
- if (2 == sscanf(r->protocol, "HTTP/%u.%u%n", &major, &minor, &n)
- && minor < HTTP_VERSION(1,0)) /* don't allow HTTP/0.1000 */
- r->proto_num = HTTP_VERSION(major, minor);
+ /* Avoid sscanf in the common case */
+ if (strlen(r->protocol) == 8
+ && r->protocol[0] == 'H' && r->protocol[1] == 'T'
+ && r->protocol[2] == 'T' && r->protocol[3] == 'P'
+ && r->protocol[4] == '/' && ap_isdigit(r->protocol[5])
+ && r->protocol[6] == '.' && ap_isdigit(r->protocol[7])) {
+ r->proto_num = HTTP_VERSION(r->protocol[5] - '0', r->protocol[7] - '0');
+ }
else {
- r->proto_num = HTTP_VERSION(1,0);
- n = 0;
+ kruft = ap_palloc(r->pool, strlen(r->protocol)+1);
+ if (2 == sscanf(r->protocol, "HTTP/%u.%u%s", &major, &minor, kruft)
+ && minor < HTTP_VERSION(1,0)) /* don't allow HTTP/0.1000 */
+ r->proto_num = HTTP_VERSION(major, minor);
+ else {
+ r->proto_num = HTTP_VERSION(1,0);
+ valid_protocol = 0;
+ }
}
/* Check for a valid protocol, and disallow everything but whitespace
- * after the protocol string */
- while (ap_isspace(r->protocol[n]))
- ++n;
- if (r->protocol[n] != '\0') {
- r->status = HTTP_BAD_REQUEST;
- r->proto_num = HTTP_VERSION(1,0);
- r->protocol = ap_pstrdup(r->pool, "HTTP/1.0");
- ap_table_setn(r->notes, "error-notes",
- "The request line contained invalid characters "
- "following the protocol string.<P>\n");
- return 0;
+ * after the protocol string. A protocol string of nothing but
+ * whitespace is considered valid */
+ if (ap_protocol_req_check && !valid_protocol) {
+ int n = 0;
+ while (ap_isspace(r->protocol[n]))
+ ++n;
+ if (r->protocol[n] != '\0') {
+ r->status = HTTP_BAD_REQUEST;
+ r->proto_num = HTTP_VERSION(1,0);
+ r->protocol = ap_pstrdup(r->pool, "HTTP/1.0");
+ ap_table_setn(r->notes, "error-notes",
+ "The request line contained invalid characters "
+ "following the protocol string.<P>\n");
+ return 0;
+ }
}
return 1;
--
===========================================================================
Jim Jagielski [|] jim@jaguNET.com [|] http://www.jaguNET.com/
"A society that will trade a little liberty for a little order
will lose both and deserve neither" - T.Jefferson