From 7da3ea67e4137a0b708e98857e7c5777d1880c39 Mon Sep 17 00:00:00 2001 From: Amos Jeffries Date: Tue, 19 Oct 2010 23:03:14 -0600 Subject: [PATCH] Author: Alex Rousskov 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 --- src/HttpHeader.cc | 2 +- src/HttpReply.cc | 64 +++++++++++++++++++++++++++++++++++++++++++++++ src/HttpReply.h | 5 ++++ src/http.cc | 2 ++ 4 files changed, 72 insertions(+), 1 deletion(-) diff --git a/src/HttpHeader.cc b/src/HttpHeader.cc index 38807f4d8b..555b082390 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 6110a2b2a3..984e09e938 100644 --- a/src/HttpReply.cc +++ b/src/HttpReply.cc @@ -629,3 +629,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 33b471d4a9..d44be465ec 100644 --- a/src/HttpReply.h +++ b/src/HttpReply.h @@ -140,6 +140,9 @@ public: */ HttpReply *clone() const; + /// Remove Warnings with warn-date different from Date value + void removeStaleWarnings(); + private: /** initialize */ void init(); @@ -162,6 +165,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 89542c87fc..2eea123727 100644 --- a/src/http.cc +++ b/src/http.cc @@ -709,6 +709,8 @@ HttpStateData::processReplyHeader() readBuf->consume(header_bytes_read); } + newrep->removeStaleWarnings(); + /* Skip 1xx messages for now. Advertised in Via as an internal 1.0 hop */ if (newrep->sline.protocol == PROTO_HTTP && newrep->sline.status >= 100 && newrep->sline.status < 200) { -- 2.47.2