From: Colm MacCarthaigh Date: Fri, 27 Jan 2006 00:20:28 +0000 (+0000) Subject: Merge r103331 from trunk: X-Git-Tag: 2.0.56~67 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=91a1e172f9fcc8f6eaaf65b090501df1afc5110d;p=thirdparty%2Fapache%2Fhttpd.git 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 --- diff --git a/CHANGES b/CHANGES index f3581605e59..24947a6a081 100644 --- a/CHANGES +++ b/CHANGES @@ -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] diff --git a/STATUS b/STATUS index b5f45dfdada..8c73ba42808 100644 --- a/STATUS +++ b/STATUS @@ -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 diff --git a/modules/loggers/mod_log_config.c b/modules/loggers/mod_log_config.c index a04699955f1..8187f14e923 100644 --- a/modules/loggers/mod_log_config.c +++ b/modules/loggers/mod_log_config.c @@ -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); } - return ap_escape_logitem(r->pool, apr_table_get(r->err_headers_out, a)); + else { + cp = apr_table_get(r->headers_out, a); + } + + return ap_escape_logitem(r->pool, cp); } static const char *log_note(request_rec *r, char *a)