Commit b9b274a1 authored by Bill Stoddard's avatar Bill Stoddard
Browse files

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.

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
parent 8aa41688
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
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 
+23 −10
Original line number Diff line number Diff line
@@ -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,15 +741,26 @@ 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 (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); */

    if (2 == sscanf(r->protocol, "HTTP/%u.%u", &major, &minor)
    /* 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