Commit cd6ea620 authored by Colm MacCarthaigh's avatar Colm MacCarthaigh
Browse files

Merge r103331 from trunk:

cleanup log_header_out function:
- no need to ask r->err_headers_out, because it's already merged with
  r->headers_out at this stage
- allow multiple headers like Set-Cookie to be logged properly

PR: 27787  

Submitted by: nd


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.0.x@372669 13f79535-47bb-0310-9956-ffa450edef68
parent f4d34941
Loading
Loading
Loading
Loading
+3 −0
Changes for CHANGES: 3 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -14,6 +14,9 @@ Changes with Apache 2.0.56
     ap_escape_html so we escape quotes.  Reported by JPCERT.
     [Mark Cox]
  *) mod_log_config now logs all Set-Cookie headers if the %{Set-Cookie}o
     format is used. PR 27787.  [André Malo]
  *) mod_cgid: Refuse to work on Solaris 10 due to OS bugs.  PR 34264.
     [Justin Erenkrantz]
+0 −11
Changes for STATUS: 0 added lines, 11 removed lines.
Original line number Diff line number Diff line
@@ -114,17 +114,6 @@ PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
         http://svn.apache.org/viewcvs?view=rev&rev=154319
       +1: stoddard, striker, wrowe (as corrected in subsequent patches)

    *) mod_log_config: Cleanup log_header_out function to allow multiple headers
       like Set-Cookie to be logged properly. PR 27787 (2.0 + 1.3)
         http://people.apache.org/~colm/httpd-2.0-mod_log_config.patch
       jerenkrantz asks: Isn't this what apr_table_merge is for?
       nd replies: yep. But cookies won't be merged, because browsers don't
                   support it.
       jerenkrantz: Couldn't we copy the table and merge the values somehow?
                    This just seems like a lot of code to duplicate what we
                    have already.  *shrug*  Regardless, patch looks okay...
       +1: nd, jerenkrantz, colm

PATCHES PROPOSED TO BACKPORT FROM TRUNK:
  [ please place SVN revisions from trunk here, so it is easy to
    identify exactly what the proposed changes are!  Add all new
+75 −4
Changes for modules/loggers/mod_log_config.c: 75 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -407,16 +407,87 @@ static const char *log_header_in(request_rec *r, char *a)
    return ap_escape_logitem(r->pool, apr_table_get(r->headers_in, a));
}

static APR_INLINE char *find_multiple_headers(apr_pool_t *pool,
                                              const apr_table_t *table,
                                              const char *key)
{
    const apr_array_header_t *elts;
    const apr_table_entry_t *t_elt;
    const apr_table_entry_t *t_end;
    apr_size_t len;
    struct sle {
        struct sle *next;
        const char *value;
        apr_size_t len;
    } *result_list, *rp;

    elts = apr_table_elts(table);

    if (!elts->nelts) {
        return NULL;
    }

    t_elt = (const apr_table_entry_t *)elts->elts;
    t_end = t_elt + elts->nelts;
    len = 1; /* \0 */
    result_list = rp = NULL;

    do {
        if (!strcasecmp(t_elt->key, key)) {
            if (!result_list) {
                result_list = rp = apr_palloc(pool, sizeof(*rp));
            }
            else {
                rp = rp->next = apr_palloc(pool, sizeof(*rp));
                len += 2; /* ", " */
            }

            rp->next = NULL;
            rp->value = t_elt->val;
            rp->len = strlen(rp->value);

            len += rp->len;
        }
        ++t_elt;
    } while (t_elt < t_end);

    if (result_list) {
        char *result = apr_palloc(pool, len);
        char *cp = result;

        rp = result_list;
        while (rp) {
            if (rp != result_list) {
                *cp++ = ',';
                *cp++ = ' ';
            }
            memcpy(cp, rp->value, rp->len);
            cp += rp->len;
            rp = rp->next;
        }
        *cp = '\0';

        return result;
    }

    return NULL;
}

static const char *log_header_out(request_rec *r, char *a)
{
    const char *cp = apr_table_get(r->headers_out, a);
    const char *cp = NULL;

    if (!strcasecmp(a, "Content-type") && r->content_type) {
        cp = ap_field_noparam(r->pool, r->content_type);
    }
    if (cp) {
        return ap_escape_logitem(r->pool, cp);
    else if (!strcasecmp(a, "Set-Cookie")) {
        cp = find_multiple_headers(r->pool, r->headers_out, a);
    }
    else {
        cp = apr_table_get(r->headers_out, a);
    }
    return ap_escape_logitem(r->pool, apr_table_get(r->err_headers_out, a));

    return ap_escape_logitem(r->pool, cp);
}

static const char *log_note(request_rec *r, char *a)