Address Alex and Amos' comments.

- Use bool instead of int for urlIsRelative.
- Document what leads to a NULL return in urlMakeAbsolute and mention the
  responsibility of the caller to free the result in the non-NULL case.
- Declare variables closer to where they're used.
- Fix indentation.
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: [EMAIL PROTECTED]
# target_branch: http://www.squid-cache.org/bzr/squid3/trunk/
# testament_sha1: 623f171d6e06626c28aa1dd5e02cf8b18daff6ca
# timestamp: 2008-09-03 14:43:27 +1000
# base_revision_id: [EMAIL PROTECTED]
#   ejhnqdep2qm6qz0h
# 
# Begin patch
=== modified file 'src/HttpRequestMethod.cc'
--- src/HttpRequestMethod.cc	2008-06-20 04:43:01 +0000
+++ src/HttpRequestMethod.cc	2008-08-29 00:56:35 +0000
@@ -243,11 +243,16 @@
         case METHOD_PURGE:
             return true;
 
-        /* all others */
+        /*
+         * RFC 2616 sayeth, in section 13.10, final paragraph:
+         * A cache that passes through requests for methods it does not
+         * understand SHOULD invalidate any entities referred to by the
+         * Request-URI.
+         */
         case METHOD_OTHER:
         default:
-            return false; // be conservative: we do not know some methods specs
+            return true;
 	}
 
-    return false; // not reached
+    return true; // not reached, but just in case
 }

=== modified file 'src/Server.cc'
--- src/Server.cc	2008-07-22 12:33:41 +0000
+++ src/Server.cc	2008-09-03 01:00:39 +0000
@@ -402,11 +402,35 @@
 
 // purges entries that match the value of a given HTTP [response] header
 static void
-purgeEntriesByHeader(const char *reqUrl, HttpMsg *rep, http_hdr_type hdr)
+purgeEntriesByHeader(const HttpRequest *req, const char *reqUrl, HttpMsg *rep, http_hdr_type hdr)
 {
-    if (const char *url = rep->header.getStr(hdr))
-        if (sameUrlHosts(reqUrl, url)) // prevent purging DoS, per RFC 2616
-            purgeEntriesByUrl(url);
+    const char *hdrUrl, *absUrl;
+    
+    absUrl = NULL;
+    hdrUrl = rep->header.getStr(hdr);
+    if (hdrUrl == NULL) {
+        return;
+    }
+    
+    /*
+     * If the URL is relative, make it absolute so we can find it.
+     * If it's absolute, make sure the host parts match to avoid DOS attacks
+     * as per RFC 2616 13.10.
+     */
+    if (urlIsRelative(hdrUrl)) {
+        absUrl = urlMakeAbsolute(req, hdrUrl);
+        if (absUrl != NULL) {
+            hdrUrl = absUrl;
+        }
+    } else if (!sameUrlHosts(reqUrl, hdrUrl)) {
+        return;
+    }
+    
+    purgeEntriesByUrl(hdrUrl);
+    
+    if (absUrl != NULL) {
+        safe_free(absUrl);
+    }
 }
 
 // some HTTP methods should purge matching cache entries
@@ -425,8 +449,8 @@
    const char *reqUrl = urlCanonical(request);
    debugs(88, 5, "maybe purging due to " << RequestMethodStr(request->method) << ' ' << reqUrl);
    purgeEntriesByUrl(reqUrl);
-   purgeEntriesByHeader(reqUrl, theFinalReply, HDR_LOCATION);
-   purgeEntriesByHeader(reqUrl, theFinalReply, HDR_CONTENT_LOCATION);
+   purgeEntriesByHeader(request, reqUrl, theFinalReply, HDR_LOCATION);
+   purgeEntriesByHeader(request, reqUrl, theFinalReply, HDR_CONTENT_LOCATION);
 }
 
 // called (usually by kids) when we have final (possibly adapted) reply headers

=== modified file 'src/protos.h'
--- src/protos.h	2008-07-17 12:38:06 +0000
+++ src/protos.h	2008-09-03 04:40:31 +0000
@@ -638,6 +638,8 @@
 SQUIDCEXTERN void urlInitialize(void);
 SQUIDCEXTERN HttpRequest *urlParse(const HttpRequestMethod&, char *, HttpRequest *request = NULL);
 SQUIDCEXTERN const char *urlCanonical(HttpRequest *);
+SQUIDCEXTERN bool urlIsRelative(const char *);
+SQUIDCEXTERN char *urlMakeAbsolute(const HttpRequest *, const char *);
 SQUIDCEXTERN char *urlRInternal(const char *host, u_short port, const char *dir, const char *name);
 SQUIDCEXTERN char *urlInternal(const char *dir, const char *name);
 SQUIDCEXTERN int matchDomainName(const char *host, const char *domain);

=== modified file 'src/url.cc'
--- src/url.cc	2008-04-10 11:29:39 +0000
+++ src/url.cc	2008-09-03 04:42:27 +0000
@@ -533,6 +533,105 @@
 }
 
 /*
+ * Test if a URL is relative.
+ *
+ * RFC 2396, Section 5 (Page 17) implies that in a relative URL, a '/' will
+ * appear before a ':'.
+ */
+bool
+urlIsRelative(const char *url)
+{
+    const char *p;
+
+    if (url == NULL) {
+        return (false);
+    }
+    if (*url == '\0') {
+        return (false);
+    }
+
+    for (p = url; *p != '\0' && *p != ':' && *p != '/'; p++);
+
+    if (*p == ':') {
+        return (false);
+    }
+    return (true);
+}
+
+/*
+ * Convert a relative URL to an absolute URL using the context of a given
+ * request.
+ *
+ * It is assumed that you have already ensured that the URL is relative.
+ *
+ * If NULL is returned it is an indication that the method in use in the
+ * request does not distinguish between relative and absolute and you should
+ * use the url unchanged.
+ *
+ * If non-NULL is returned, it is up to the caller to free the resulting
+ * memory using safe_free().
+ */
+char *
+urlMakeAbsolute(const HttpRequest * req, const char *relUrl)
+{
+
+    if (req->method.id() == METHOD_CONNECT) {
+        return (NULL);
+    }
+    
+    char *urlbuf = (char *)xmalloc(MAX_URL * sizeof(char));
+    
+    if (req->protocol == PROTO_URN) {
+        snprintf(urlbuf, MAX_URL, "urn:%s", req->urlpath.buf());
+        return (urlbuf);
+    }
+        
+    size_t urllen;
+
+    if (req->port != urlDefaultPort(req->protocol)) {
+        urllen = snprintf(urlbuf, MAX_URL, "%s://%s%s%s:%d",
+            ProtocolStr[req->protocol],
+            req->login,
+            *req->login ? "@" : null_string,
+            req->GetHost(),
+            req->port
+        );
+    } else {
+        urllen = snprintf(urlbuf, MAX_URL, "%s://%s%s%s",
+            ProtocolStr[req->protocol],
+            req->login,
+            *req->login ? "@" : null_string,
+            req->GetHost()
+        );
+    }
+
+    if (relUrl[0] == '/') {
+        strncpy(&urlbuf[urllen], relUrl, MAX_URL - urllen - 1);
+    } else {
+        const char *path = req->urlpath.buf();
+        const char *last_slash = strrchr(path, '/');
+
+        if (last_slash == NULL) {
+               urlbuf[urllen++] = '/';
+            strncpy(&urlbuf[urllen], relUrl, MAX_URL - urllen - 1);
+        } else {
+            last_slash++;
+            size_t pathlen = last_slash - path;
+            if (pathlen > MAX_URL - urllen - 1) {
+                pathlen = MAX_URL - urllen - 1;
+            }
+            strncpy(&urlbuf[urllen], path, pathlen);
+            urllen += pathlen;
+            if (urllen + 1 < MAX_URL) {
+                strncpy(&urlbuf[urllen], relUrl, MAX_URL - urllen - 1);
+            }
+        }
+    }
+
+    return (urlbuf);
+}
+
+/*
  * matchDomainName() compares a hostname with a domainname according
  * to the following rules:
  * 

# Begin bundle
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
UA==

Reply via email to