]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
HTTP Compliance: delete Warnings that have warning-date different from Date.
authorAlex Rousskov <rousskov@measurement-factory.com>
Fri, 10 Sep 2010 21:12:54 +0000 (15:12 -0600)
committerAlex Rousskov <rousskov@measurement-factory.com>
Fri, 10 Sep 2010 21:12:54 +0000 (15:12 -0600)
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
src/HttpReply.cc
src/HttpReply.h
src/http.cc

index ebec6d124be76f1f477517d3259a0453ae4e7650..4b9bb35b5831167f56e147b70cb187e94b3d2566 100644 (file)
@@ -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,
index 5c55886cb73d8ceb7faa252fca85a34dc3672b7b..41b6058f94805198e81f56247bc1ed9676331c7e 100644 (file)
@@ -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;
+}
index 9bd8c46ec11a2cae40ceaf9518a63afbefe9ca56..ca2a5d5b21ab84e1973377f61c255ce38b41bf28 100644 (file)
@@ -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:
index c07aba8c076a305d7089190c08e7208760fe5ac6..91e9b5a170bc0b3c30c9bf69ac6790c5af070c89 100644 (file)
@@ -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);