]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Avoid using sscanf to determine the HTTP protocol number in
authorBill Stoddard <stoddard@apache.org>
Fri, 16 Mar 2001 04:17:38 +0000 (04:17 +0000)
committerBill Stoddard <stoddard@apache.org>
Fri, 16 Mar 2001 04:17:38 +0000 (04:17 +0000)
the common case because sscanf is a performance hog. From
Mike Abbot's Accelerating Apache patch number 6.

Submitted by: Mike Abbot <mja@trudge.engr.sgi.com>
Reviewed by: Bill Stoddard

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@88523 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
server/protocol.c

diff --git a/CHANGES b/CHANGES
index 0f3944086e87ed4a22114a00c3f449804f6442d1..3824250e0b6316981108b87525163d0b2b475adf 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,8 @@
 Changes with Apache 2.0.15-dev
+  *) Avoid using sscanf to determine the HTTP protocol number in
+     the common case because sscanf is a performance hog. From
+     Mike Abbot's Accelerating Apache patch number 6.
+     [Mike Abbot <mja@trudge.engr.sgi.com>, Bill Stoddard]
 
   *) Fix a security exposure in mod_access.  Previously when IPv6 
      listening sockets were used, allow/deny-from-IPv4-address rules 
index b6838b44241a42a942829e1bf1c92bf799f5fdb4..aa8308e05d324caf3f092925ab370d7e8d151824 100644 (file)
@@ -664,6 +664,8 @@ static int read_request_line(request_rec *r)
     char l[DEFAULT_LIMIT_REQUEST_LINE + 2]; /* getline's two extra for \n\0 */
     const char *ll = l;
     const char *uri;
+    const char *pro;
+
 #if 0
     conn_rec *conn = r->connection;
 #endif
@@ -739,16 +741,27 @@ static int read_request_line(request_rec *r)
         return 0;
     }
 
-    r->assbackwards = (ll[0] == '\0');
-    r->protocol = apr_pstrdup(r->pool, ll[0] ? ll : "HTTP/0.9");
-/* XXX If we want to keep track of the Method, the protocol module should do
- * it.  That support isn't in the scoreboard yet.  Hopefully next week 
- * sometime.   rbb
-    ap_update_connection_status(conn->id, "Protocol", r->protocol); 
- */
-
-    if (2 == sscanf(r->protocol, "HTTP/%u.%u", &major, &minor)
-      && minor < HTTP_VERSION(1,0))    /* don't allow HTTP/0.1000 */
+    if (ll[0]) {
+        r->assbackwards = 0;
+        pro = ll;
+        len = strlen(ll);
+    } else {
+        r->assbackwards = 1;
+        pro = "HTTP/0.9";
+        len = 8;
+    }
+    r->protocol = apr_pstrndup(r->pool, pro, len);
+
+    /* XXX ap_update_connection_status(conn->id, "Protocol", r->protocol); */
+
+    /* Avoid sscanf in the common case */
+    if (len == 8 &&
+        pro[0] == 'H' && pro[1] == 'T' && pro[2] == 'T' && pro[3] == 'P' &&
+        pro[4] == '/' && apr_isdigit(pro[5]) && pro[6] == '.' &&
+        apr_isdigit(pro[7])) {
+       r->proto_num = HTTP_VERSION(pro[5] - '0', pro[7] - '0');
+    } else if (2 == sscanf(r->protocol, "HTTP/%u.%u", &major, &minor)
+               && 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);