From: Amos Jeffries Date: Sat, 30 Jan 2010 01:08:33 +0000 (+1300) Subject: Author: Christos Tsantilas X-Git-Tag: SQUID_3_1_0_16~10 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e642fbef620b4d0f5b6c67d26f5f0d263a0c0fda;p=thirdparty%2Fsquid.git Author: Christos Tsantilas Add the http::>ha format code and make http::>h log original request headers This patch: - Modify the existin "http::>h format code to log HTTP request headers before any adaptation and redirection - Add the new format code "http::>ha" which allow the user to log HTTP request header or header fields after adaptation and redirection. This is a Measurement Factory project. --- diff --git a/doc/release-notes/release-3.1.sgml b/doc/release-notes/release-3.1.sgml index 861a4bd750..7ec83c90a4 100644 --- a/doc/release-notes/release-3.1.sgml +++ b/doc/release-notes/release-3.1.sgml @@ -1128,11 +1128,13 @@ NOCOMMENT_START logformat

New log format tag sets %icap::* %adapt::* for adaptation information. %Hs tag deprecated and replaced by request/reply specific >Hs and <Hs + new %ha option to log original headers received from client (after adaptation and redirection) HTTP request/reply format tags may now be optionally prefixed with http::. Old forms will be deprecated in some as yet undecided future release. dt Total time spent making DNS lookups (milliseconds) + [http::]>ha The HTTP request headers after adaptation and redirection. [http::]>Hs HTTP status code sent to the client [http::]sh Received HTTP request headers size diff --git a/src/AccessLogEntry.h b/src/AccessLogEntry.h index 9410ba2588..cd5e3c2bbd 100644 --- a/src/AccessLogEntry.h +++ b/src/AccessLogEntry.h @@ -47,7 +47,8 @@ class AccessLogEntry { public: - AccessLogEntry() : url(NULL) , reply(NULL), request(NULL) {} + AccessLogEntry() : url(NULL) , reply(NULL), request(NULL), + adapted_request(NULL) {} const char *url; @@ -126,12 +127,17 @@ public: public: Headers() : request(NULL), + adapted_request(NULL), + #if ICAP_CLIENT icap(NULL), #endif reply(NULL) {} - char *request; + char *request; //< virgin HTTP request headers + + char *adapted_request; //< HTTP request headers after adaptation and redirection + #if ICAP_CLIENT char * icap; ///< last matching ICAP response header. @@ -151,7 +157,9 @@ public: } _private; HierarchyLogEntry hier; HttpReply *reply; - HttpRequest *request; + HttpRequest *request; //< virgin HTTP request + HttpRequest *adapted_request; //< HTTP request after adaptation and redirection + #if ICAP_CLIENT /** \brief This subclass holds log info for ICAP part of request diff --git a/src/access_log.cc b/src/access_log.cc index d10a80ffbc..56340ed25f 100644 --- a/src/access_log.cc +++ b/src/access_log.cc @@ -351,6 +351,10 @@ typedef enum { LFT_REQUEST_HEADER_ELEM, LFT_REQUEST_ALL_HEADERS, + LFT_ADAPTED_REQUEST_HEADER, + LFT_ADAPTED_REQUEST_HEADER_ELEM, + LFT_ADAPTED_REQUEST_ALL_HEADERS, + LFT_REPLY_HEADER, LFT_REPLY_HEADER_ELEM, LFT_REPLY_ALL_HEADERS, @@ -500,6 +504,8 @@ struct logformat_token_table_entry logformat_token_table[] = { {"ha", LFT_ADAPTED_REQUEST_HEADER}, + {">ha", LFT_ADAPTED_REQUEST_ALL_HEADERS}, {">h", LFT_REQUEST_HEADER}, {">h", LFT_REQUEST_ALL_HEADERS}, {"request) + sb = al->adapted_request->header.getByName(fmt->data.header.header); + + out = sb.termedBuf(); + + quote = 1; + + break; + case LFT_REPLY_HEADER: if (al->reply) sb = al->reply->header.getByName(fmt->data.header.header); @@ -929,6 +946,16 @@ accessLogCustom(AccessLogEntry * al, customlog * log) break; + case LFT_ADAPTED_REQUEST_HEADER_ELEM: + if (al->adapted_request) + sb = al->adapted_request->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator); + + out = sb.termedBuf(); + + quote = 1; + + break; + case LFT_REPLY_HEADER_ELEM: if (al->reply) sb = al->reply->header.getByNameListMember(fmt->data.header.header, fmt->data.header.element, fmt->data.header.separator); @@ -946,6 +973,13 @@ accessLogCustom(AccessLogEntry * al, customlog * log) break; + case LFT_ADAPTED_REQUEST_ALL_HEADERS: + out = al->headers.adapted_request; + + quote = 1; + + break; + case LFT_REPLY_ALL_HEADERS: out = al->headers.reply; @@ -1357,6 +1391,8 @@ done: case LFT_ICAP_REP_HEADER: #endif + case LFT_ADAPTED_REQUEST_HEADER: + case LFT_REQUEST_HEADER: case LFT_REPLY_HEADER: @@ -1379,6 +1415,11 @@ done: case LFT_REQUEST_HEADER: lt->type = LFT_REQUEST_HEADER_ELEM; break; + + case LFT_ADAPTED_REQUEST_HEADER: + lt->type = LFT_ADAPTED_REQUEST_HEADER_ELEM; + break; + case LFT_REPLY_HEADER: lt->type = LFT_REPLY_HEADER_ELEM; break; @@ -1404,6 +1445,11 @@ done: case LFT_REQUEST_HEADER: lt->type = LFT_REQUEST_ALL_HEADERS; break; + + case LFT_ADAPTED_REQUEST_HEADER: + lt->type = LFT_ADAPTED_REQUEST_ALL_HEADERS; + break; + case LFT_REPLY_HEADER: lt->type = LFT_REPLY_ALL_HEADERS; break; @@ -1517,7 +1563,7 @@ accessLogDumpLogFormat(StoreEntry * entry, const char *name, logformat * definit case LFT_ICAP_REP_HEADER_ELEM: #endif case LFT_REQUEST_HEADER_ELEM: - + case LFT_ADAPTED_REQUEST_HEADER_ELEM: case LFT_REPLY_HEADER_ELEM: if (t->data.header.separator != ',') @@ -1531,6 +1577,9 @@ accessLogDumpLogFormat(StoreEntry * entry, const char *name, logformat * definit case LFT_REQUEST_HEADER_ELEM: type = LFT_REQUEST_HEADER_ELEM; break; + case LFT_ADAPTED_REQUEST_HEADER_ELEM: + type = LFT_ADAPTED_REQUEST_HEADER_ELEM; + break; case LFT_REPLY_HEADER_ELEM: type = LFT_REPLY_HEADER_ELEM; break; @@ -1552,7 +1601,7 @@ accessLogDumpLogFormat(StoreEntry * entry, const char *name, logformat * definit break; case LFT_REQUEST_ALL_HEADERS: - + case LFT_ADAPTED_REQUEST_ALL_HEADERS: case LFT_REPLY_ALL_HEADERS: #if ICAP_CLIENT @@ -1565,6 +1614,9 @@ accessLogDumpLogFormat(StoreEntry * entry, const char *name, logformat * definit case LFT_REQUEST_ALL_HEADERS: type = LFT_REQUEST_HEADER; break; + case LFT_ADAPTED_REQUEST_ALL_HEADERS: + type = LFT_ADAPTED_REQUEST_HEADER; + break; case LFT_REPLY_ALL_HEADERS: type = LFT_REPLY_HEADER; break; @@ -2349,6 +2401,9 @@ accessLogFreeMemory(AccessLogEntry * aLogEntry) safe_free(aLogEntry->headers.reply); safe_free(aLogEntry->cache.authuser); + safe_free(aLogEntry->headers.adapted_request); + HTTPMSGUNLOCK(aLogEntry->adapted_request); + HTTPMSGUNLOCK(aLogEntry->reply); HTTPMSGUNLOCK(aLogEntry->request); #if ICAP_CLIENT diff --git a/src/cf.data.pre b/src/cf.data.pre index e6b1d2b0b8..ca234e95bf 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -2408,8 +2408,10 @@ DOC_START HTTP cache related format codes: - [http::]>h Request header. Optional header name argument + [http::]>h Original request header. Optional header name argument on the format header[:[separator]element] + [http::]>ha The HTTP request headers after adaptation and redirection. + Optional header name argument as for >h [http::]h [http::]un User name diff --git a/src/client_side.cc b/src/client_side.cc index 026a4f5b04..da4fc2bc05 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -460,7 +460,17 @@ prepareLogWithRequestDetails(HttpRequest * request, AccessLogEntry * aLogEntry) mb.init(); packerToMemInit(&p, &mb); request->header.packInto(&p); - aLogEntry->headers.request = xstrdup(mb.buf); + //This is the request after adaptation or redirection + aLogEntry->headers.adapted_request = xstrdup(mb.buf); + + // the virgin request is saved to aLogEntry->request + if (aLogEntry->request) { + packerClean(&p); + mb.reset(); + packerToMemInit(&p, &mb); + aLogEntry->request->header.packInto(&p); + aLogEntry->headers.request = xstrdup(mb.buf); + } #if ICAP_CLIENT packerClean(&p); @@ -558,7 +568,7 @@ ClientHttpRequest::logRequest() if (!Config.accessList.log || checklist->fastCheck()) { if (request) - al.request = HTTPMSGLOCK(request); + al.adapted_request = HTTPMSGLOCK(request); accessLogLog(&al, checklist); updateCounters(); diff --git a/src/client_side_request.cc b/src/client_side_request.cc index 488acb2607..afe80fe0d7 100644 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@ -1243,6 +1243,10 @@ ClientHttpRequest::doCallouts() { assert(calloutContext); + /*Save the original request for logging purposes*/ + if (!calloutContext->http->al.request) + calloutContext->http->al.request = HTTPMSGLOCK(request); + if (!calloutContext->http_access_done) { debugs(83, 3, HERE << "Doing calloutContext->clientAccessCheck()"); calloutContext->http_access_done = true;