From: Stefan Eissing Date: Mon, 6 Jun 2016 13:45:58 +0000 (+0000) Subject: Merge of r1733537 from trunk: X-Git-Tag: 2.4.21~91 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d451249f1f8ef9531ffdae5c98ccf8380665e787;p=apache Merge of r1733537 from trunk: ab: caseless matching for http heaers git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1746997 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/support/ab.c b/support/ab.c index 02db919008..3add10f3c2 100644 --- a/support/ab.c +++ b/support/ab.c @@ -425,6 +425,41 @@ static char *xstrdup(const char *s) return ret; } +/* + * Similar to standard strstr() but we ignore case in this version. + * Copied from ap_strcasestr(). + */ +static char *xstrcasestr(const char *s1, const char *s2) +{ + char *p1, *p2; + if (*s2 == '\0') { + /* an empty s2 */ + return((char *)s1); + } + while(1) { + for ( ; (*s1 != '\0') && (apr_tolower(*s1) != apr_tolower(*s2)); s1++); + if (*s1 == '\0') { + return(NULL); + } + /* found first character of s2, see if the rest matches */ + p1 = (char *)s1; + p2 = (char *)s2; + for (++p1, ++p2; apr_tolower(*p1) == apr_tolower(*p2); ++p1, ++p2) { + if (*p1 == '\0') { + /* both strings ended together */ + return((char *)s1); + } + } + if (*p2 == '\0') { + /* second string ended, a match */ + break; + } + /* didn't find a match here, try starting at next character in s1 */ + s1++; + } + return((char *)s1); +} + /* pool abort function */ static int abort_on_oom(int retcode) { @@ -1516,7 +1551,7 @@ static void read_connection(struct connection * c) */ char *p, *q; size_t len = 0; - p = strstr(c->cbuff, "Server:"); + p = xstrcasestr(c->cbuff, "Server:"); q = servername; if (p) { p += 8; @@ -1553,22 +1588,15 @@ static void read_connection(struct connection * c) } c->gotheader = 1; *s = 0; /* terminate at end of header */ - if (keepalive && - (strstr(c->cbuff, "Keep-Alive") - || strstr(c->cbuff, "keep-alive"))) { /* for benefit of MSIIS */ + if (keepalive && xstrcasestr(c->cbuff, "Keep-Alive")) { char *cl; - cl = strstr(c->cbuff, "Content-Length:"); - /* handle NCSA, which sends Content-length: */ - if (!cl) - cl = strstr(c->cbuff, "Content-length:"); - if (cl) { - c->keepalive = 1; + c->keepalive = 1; + cl = xstrcasestr(c->cbuff, "Content-Length:"); + if (cl && method != HEAD) { /* response to HEAD doesn't have entity body */ - c->length = method != HEAD ? atoi(cl + 16) : 0; + c->length = atoi(cl + 16); } - /* The response may not have a Content-Length header */ - if (!cl) { - c->keepalive = 1; + else { c->length = 0; } }