--- /dev/null
+------------------------------------------------------------
+revno: 14073
+revision-id: squid3@treenet.co.nz-20160817051037-p0kaj2iw2u4u8iqj
+parent: squid3@treenet.co.nz-20160817025828-s4102klt2ei25tsm
+fixes bug: http://bugs.squid-cache.org/show_bug.cgi?id=4563
+committer: Amos Jeffries <squid3@treenet.co.nz>
+branch nick: 3.5
+timestamp: Wed 2016-08-17 17:10:37 +1200
+message:
+ Bug 4563: duplicate code in httpMakeVaryMark
+------------------------------------------------------------
+# Bazaar merge directive format 2 (Bazaar 0.90)
+# revision_id: squid3@treenet.co.nz-20160817051037-p0kaj2iw2u4u8iqj
+# target_branch: http://bzr.squid-cache.org/bzr/squid3/3.5
+# testament_sha1: bba9a17715b8759e9d70db2c75f70f3c6152ae8a
+# timestamp: 2016-08-17 05:50:53 +0000
+# source_branch: http://bzr.squid-cache.org/bzr/squid3/3.5
+# base_revision_id: squid3@treenet.co.nz-20160817025828-\
+# s4102klt2ei25tsm
+#
+# Begin patch
+=== modified file 'src/http.cc'
+--- src/http.cc 2016-04-01 06:15:31 +0000
++++ src/http.cc 2016-08-17 05:10:37 +0000
+@@ -572,6 +572,38 @@
+ /* NOTREACHED */
+ }
+
++/// assemble a variant key (vary-mark) from the given Vary header and HTTP request
++static void
++assembleVaryKey(String &vary, SBuf &vstr, const HttpRequest &request)
++{
++ static const SBuf asterisk("*");
++ const char *pos = nullptr;
++ const char *item = nullptr;
++ int ilen = 0;
++
++ while (strListGetItem(&vary, ',', &item, &ilen, &pos)) {
++ SBuf name(item, ilen);
++ if (name == asterisk) {
++ vstr.clear();
++ break;
++ }
++ name.toLower();
++ if (!vstr.isEmpty())
++ vstr.append(", ", 2);
++ vstr.append(name);
++ String hdr(request.header.getByName(name.c_str()));
++ const char *value = hdr.termedBuf();
++ if (value) {
++ value = rfc1738_escape_part(value);
++ vstr.append("=\"", 2);
++ vstr.append(value);
++ vstr.append("\"", 1);
++ }
++
++ hdr.clean();
++ }
++}
++
+ /*
+ * For Vary, store the relevant request headers as
+ * virtual headers in the reply
+@@ -580,81 +612,16 @@
+ SBuf
+ httpMakeVaryMark(HttpRequest * request, HttpReply const * reply)
+ {
+- String vary, hdr;
+- const char *pos = NULL;
+- const char *item;
+- const char *value;
+- int ilen;
+ SBuf vstr;
+- static const SBuf asterisk("*");
++ String vary;
+
+ vary = reply->header.getList(HDR_VARY);
+-
+- while (strListGetItem(&vary, ',', &item, &ilen, &pos)) {
+- char *name = (char *)xmalloc(ilen + 1);
+- xstrncpy(name, item, ilen + 1);
+- Tolower(name);
+-
+- if (strcmp(name, "*") == 0) {
+- /* Can not handle "Vary: *" withtout ETag support */
+- safe_free(name);
+- vstr.clear();
+- break;
+- }
+-
+- if (!vstr.isEmpty())
+- vstr.append(", ", 2);
+- vstr.append(name);
+- hdr = request->header.getByName(name);
+- safe_free(name);
+- value = hdr.termedBuf();
+-
+- if (value) {
+- value = rfc1738_escape_part(value);
+- vstr.append("=\"", 2);
+- vstr.append(value);
+- vstr.append("\"", 1);
+- }
+-
+- hdr.clean();
+- }
+-
++ assembleVaryKey(vary, vstr, *request);
++
++#if X_ACCELERATOR_VARY
+ vary.clean();
+-#if X_ACCELERATOR_VARY
+-
+- pos = NULL;
+ vary = reply->header.getList(HDR_X_ACCELERATOR_VARY);
+-
+- while (strListGetItem(&vary, ',', &item, &ilen, &pos)) {
+- char *name = (char *)xmalloc(ilen + 1);
+- xstrncpy(name, item, ilen + 1);
+- Tolower(name);
+-
+- if (strcmp(name, "*") == 0) {
+- /* Can not handle "Vary: *" withtout ETag support */
+- safe_free(name);
+- vstr.clear();
+- break;
+- }
+-
+- if (!vstr.isEmpty())
+- vstr.append(", ", 2);
+- vstr.append(name);
+- hdr = request->header.getByName(name);
+- safe_free(name);
+- value = hdr.termedBuf();
+-
+- if (value) {
+- value = rfc1738_escape_part(value);
+- vstr.append("=\"", 2);
+- vstr.append(value);
+- vstr.append("\"", 1);
+- }
+-
+- hdr.clean();
+- }
+-
+- vary.clean();
++ assembleVaryKey(vary, vstr, *request);
+ #endif
+
+ debugs(11, 3, vstr);
+