Changes with Apache 1.3.27
+ *) Add ProtocolReqCheck directive, which determines if Apache will
+ check for a valid protocol string in the request (eg: HTTP/1.1)
+ and return HTTP_BAD_REQUEST if not valid. Versions of Apache
+ prior to 1.3.26 would silently ignore bad protocol strings, but
+ 1.3.26 included a more strict check. This makes it runtime
+ configurable. The default is On. This also removes the requirement
+ on an ANSI sscanf() implementation. [Jim Jagielski]
+
*) NetWare: implemented file locking in mod_rewrite for the NetWare
CLib platform. This fixes a bug that prevented rewrite logging
- from working. [Brad Nicholes]
+ from working. [Brad Nicholes]
Changes with Apache 1.3.26
}
#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
* 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);
(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
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.
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;