From: Alex Rousskov Date: Fri, 10 Sep 2010 21:12:54 +0000 (-0600) Subject: HTTP Compliance: delete Warnings that have warning-date different from Date. X-Git-Tag: take1~283 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c679653dc8705ef70346691f62499981ef8c3f09;p=thirdparty%2Fsquid.git HTTP Compliance: delete Warnings that have warning-date different from Date. Added HttpReply::removeStaleWarnings() method that iterates over all Warning headers and removes stale warning-values. If a reply has no valid Date header, all warning-values with warning-date are removed. Also, we remove warning-value if we failed to parse warning-date. removeStaleWarnings() is called from processReplyHeader(), after reply headers are parsed. Co-Advisor test cases: test_case/rfc2616/date-accept-fmt-warn-asctime-rfc1123 test_case/rfc2616/date-accept-fmt-warn-asctime-rfc850 test_case/rfc2616/date-accept-fmt-warn-rfc1123-asctime test_case/rfc2616/date-accept-fmt-warn-rfc1123-rfc850 test_case/rfc2616/date-accept-fmt-warn-rfc850-asctime test_case/rfc2616/date-accept-fmt-warn-rfc850-rfc1123 --- diff --git a/src/HttpHeader.cc b/src/HttpHeader.cc index ebec6d124b..4b9bb35b58 100644 --- a/src/HttpHeader.cc +++ b/src/HttpHeader.cc @@ -184,7 +184,7 @@ static http_hdr_type ListHeadersArr[] = { HDR_UPGRADE, HDR_VARY, HDR_VIA, - /* HDR_WARNING, */ + HDR_WARNING, HDR_WWW_AUTHENTICATE, HDR_AUTHENTICATION_INFO, HDR_PROXY_AUTHENTICATION_INFO, diff --git a/src/HttpReply.cc b/src/HttpReply.cc index 5c55886cb7..41b6058f94 100644 --- a/src/HttpReply.cc +++ b/src/HttpReply.cc @@ -630,3 +630,67 @@ bool HttpReply::inheritProperties(const HttpMsg *aMsg) keep_alive = aRep->keep_alive; return true; } + +void HttpReply::removeStaleWarnings() +{ + String warning; + if (header.getList(HDR_WARNING, &warning)) { + const String newWarning = removeStaleWarningValues(warning); + if (warning.size() && warning.size() == newWarning.size()) + return; // some warnings are there and none changed + header.delById(HDR_WARNING); + if (newWarning.size()) { // some warnings left + HttpHeaderEntry *const e = + new HttpHeaderEntry(HDR_WARNING, NULL, newWarning.termedBuf()); + header.addEntry(e); + } + } +} + +/** + * Remove warning-values with warn-date different from Date value from + * a single header entry. Returns a string with all valid warning-values. + */ +String HttpReply::removeStaleWarningValues(const String &value) +{ + String newValue; + const char *item = 0; + int len = 0; + const char *pos = 0; + while (strListGetItem(&value, ',', &item, &len, &pos)) { + bool keep = true; + // Does warning-value have warn-date (which contains quoted date)? + // We scan backwards, looking for two quoted strings. + // warning-value = warn-code SP warn-agent SP warn-text [SP warn-date] + const char *p = item + len - 1; + + while (p >= item && xisspace(*p)) --p; // skip whitespace + + // warning-value MUST end with quote + if (p >= item && *p == '"') { + const char *const warnDateEnd = p; + --p; + while (p >= item && *p != '"') --p; // find the next quote + + const char *warnDateBeg = p + 1; + --p; + while (p >= item && xisspace(*p)) --p; // skip whitespace + + if (p >= item && *p == '"' && warnDateBeg - p > 2) { + // found warn-text + String warnDate; + warnDate.append(warnDateBeg, warnDateEnd - warnDateBeg); + const time_t time = parse_rfc1123(warnDate.termedBuf()); + keep = (time > 0 && time == date); // keep valid and matching date + } + } + + if (keep) { + if (newValue.size()) + newValue.append(", "); + newValue.append(item, len); + } + } + + return newValue; +} diff --git a/src/HttpReply.h b/src/HttpReply.h index 9bd8c46ec1..ca2a5d5b21 100644 --- a/src/HttpReply.h +++ b/src/HttpReply.h @@ -138,6 +138,9 @@ public: */ HttpReply *clone() const; + /// Remove Warnings with warn-date different from Date value + void removeStaleWarnings(); + private: /** initialize */ void init(); @@ -160,6 +163,8 @@ private: */ void calcMaxBodySize(HttpRequest& request); + String removeStaleWarningValues(const String &value); + mutable int64_t bodySizeMax; /**< cached result of calcMaxBodySize */ protected: diff --git a/src/http.cc b/src/http.cc index c07aba8c07..91e9b5a170 100644 --- a/src/http.cc +++ b/src/http.cc @@ -707,6 +707,8 @@ HttpStateData::processReplyHeader() readBuf->consume(header_bytes_read); } + newrep->removeStaleWarnings(); + if (newrep->sline.protocol == PROTO_HTTP && newrep->sline.status >= 100 && newrep->sline.status < 200) { handle1xx(newrep); ctx_exit(ctx);