Commit 866682fe authored by Stefan Eissing's avatar Stefan Eissing
Browse files

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
parent 5892f393
Loading
Loading
Loading
Loading
+42 −14
Original line number Diff line number Diff line
@@ -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;
                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;
                }
            }