You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2018/01/15 09:00:22 UTC

httpcomponents-client git commit: HTTPCLIENT-1690: Avoid merging Content-Encoding headers coming with 304 status to cache entry, port mergeHeaders method from master

Repository: httpcomponents-client
Updated Branches:
  refs/heads/4.5.x 6e372fb53 -> f1f3a3876


HTTPCLIENT-1690: Avoid merging Content-Encoding headers coming with 304 status to cache entry, port mergeHeaders method from master


Project: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/commit/f1f3a387
Tree: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/tree/f1f3a387
Diff: http://git-wip-us.apache.org/repos/asf/httpcomponents-client/diff/f1f3a387

Branch: refs/heads/4.5.x
Commit: f1f3a387630a7e3e2d4aeda1744f3e94ca21968a
Parents: 6e372fb
Author: Sudheera Palihakkara <ca...@gmail.com>
Authored: Sun Jan 14 23:49:50 2018 +0800
Committer: Oleg Kalnichevski <ol...@apache.org>
Committed: Mon Jan 15 10:00:03 2018 +0100

----------------------------------------------------------------------
 .../impl/client/cache/CacheEntryUpdater.java    | 82 ++++++++------------
 .../client/cache/TestCacheEntryUpdater.java     | 20 +++++
 2 files changed, 53 insertions(+), 49 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/f1f3a387/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheEntryUpdater.java
----------------------------------------------------------------------
diff --git a/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheEntryUpdater.java b/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheEntryUpdater.java
index aa4c83c..f18c73c 100644
--- a/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheEntryUpdater.java
+++ b/httpclient-cache/src/main/java/org/apache/http/impl/client/cache/CacheEntryUpdater.java
@@ -27,13 +27,10 @@
 package org.apache.http.impl.client.cache;
 
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Date;
-import java.util.List;
-import java.util.ListIterator;
 
 import org.apache.http.Header;
+import org.apache.http.HeaderIterator;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpStatus;
 import org.apache.http.annotation.Contract;
@@ -43,6 +40,7 @@ import org.apache.http.client.cache.HttpCacheEntry;
 import org.apache.http.client.cache.Resource;
 import org.apache.http.client.cache.ResourceFactory;
 import org.apache.http.client.utils.DateUtils;
+import org.apache.http.message.HeaderGroup;
 import org.apache.http.protocol.HTTP;
 import org.apache.http.util.Args;
 
@@ -102,51 +100,46 @@ class CacheEntryUpdater {
     }
 
     protected Header[] mergeHeaders(final HttpCacheEntry entry, final HttpResponse response) {
-
         if (entryAndResponseHaveDateHeader(entry, response)
                 && entryDateHeaderNewerThenResponse(entry, response)) {
             // Don't merge headers, keep the entry's headers as they are newer.
             return entry.getAllHeaders();
         }
 
-        final List<Header> cacheEntryHeaderList = new ArrayList<Header>(Arrays.asList(entry
-                .getAllHeaders()));
-        removeCacheHeadersThatMatchResponse(cacheEntryHeaderList, response);
-        removeCacheEntry1xxWarnings(cacheEntryHeaderList, entry);
-        cacheEntryHeaderList.addAll(Arrays.asList(response.getAllHeaders()));
-
-        return cacheEntryHeaderList.toArray(new Header[cacheEntryHeaderList.size()]);
-    }
-
-    private void removeCacheHeadersThatMatchResponse(final List<Header> cacheEntryHeaderList,
-            final HttpResponse response) {
-        for (final Header responseHeader : response.getAllHeaders()) {
-            final ListIterator<Header> cacheEntryHeaderListIter = cacheEntryHeaderList.listIterator();
-
-            while (cacheEntryHeaderListIter.hasNext()) {
-                final String cacheEntryHeaderName = cacheEntryHeaderListIter.next().getName();
+        final HeaderGroup headerGroup = new HeaderGroup();
+        headerGroup.setHeaders(entry.getAllHeaders());
+        // Remove cache headers that match response
+        for (final HeaderIterator it = response.headerIterator(); it.hasNext(); ) {
+            final Header responseHeader = it.nextHeader();
+            // Since we do not expect a content in a 304 response, should retain the original Content-Encoding header
+            if (HTTP.CONTENT_ENCODING.equals(responseHeader.getName())) {
+                continue;
+            }
+            final Header[] matchingHeaders = headerGroup.getHeaders(responseHeader.getName());
+            for (final Header matchingHeader : matchingHeaders) {
+                headerGroup.removeHeader(matchingHeader);
+            }
 
-                if (cacheEntryHeaderName.equals(responseHeader.getName())) {
-                    cacheEntryHeaderListIter.remove();
+        }
+        // remove cache entry 1xx warnings
+        for (final HeaderIterator it = headerGroup.iterator(); it.hasNext(); ) {
+            final Header cacheHeader = it.nextHeader();
+            if (HeaderConstants.WARNING.equalsIgnoreCase(cacheHeader.getName())) {
+                final String warningValue = cacheHeader.getValue();
+                if (warningValue != null && warningValue.startsWith("1")) {
+                    it.remove();
                 }
             }
         }
-    }
-
-    private void removeCacheEntry1xxWarnings(final List<Header> cacheEntryHeaderList, final HttpCacheEntry entry) {
-        final ListIterator<Header> cacheEntryHeaderListIter = cacheEntryHeaderList.listIterator();
-
-        while (cacheEntryHeaderListIter.hasNext()) {
-            final String cacheEntryHeaderName = cacheEntryHeaderListIter.next().getName();
-
-            if (HeaderConstants.WARNING.equals(cacheEntryHeaderName)) {
-                for (final Header cacheEntryWarning : entry.getHeaders(HeaderConstants.WARNING)) {
-                    if (cacheEntryWarning.getValue().startsWith("1")) {
-                        cacheEntryHeaderListIter.remove();
-                    }
-                }
+        for (final HeaderIterator it = response.headerIterator(); it.hasNext(); ) {
+            final Header responseHeader = it.nextHeader();
+            // Since we do not expect a content in a 304 response, should avoid updating Content-Encoding header
+            if (HTTP.CONTENT_ENCODING.equals(responseHeader.getName())) {
+                continue;
             }
+            headerGroup.addHeader(responseHeader);
         }
+        return headerGroup.getAllHeaders();
     }
 
     private boolean entryDateHeaderNewerThenResponse(final HttpCacheEntry entry, final HttpResponse response) {
@@ -154,22 +147,13 @@ class CacheEntryUpdater {
                 .getValue());
         final Date responseDate = DateUtils.parseDate(response.getFirstHeader(HTTP.DATE_HEADER)
                 .getValue());
-        if (entryDate == null || responseDate == null) {
-            return false;
-        }
-        if (!entryDate.after(responseDate)) {
-            return false;
-        }
-        return true;
+        return entryDate != null && responseDate != null && entryDate.after(responseDate);
     }
 
     private boolean entryAndResponseHaveDateHeader(final HttpCacheEntry entry, final HttpResponse response) {
-        if (entry.getFirstHeader(HTTP.DATE_HEADER) != null
-                && response.getFirstHeader(HTTP.DATE_HEADER) != null) {
-            return true;
-        }
+        return entry.getFirstHeader(HTTP.DATE_HEADER) != null
+                && response.getFirstHeader(HTTP.DATE_HEADER) != null;
 
-        return false;
     }
 
 }

http://git-wip-us.apache.org/repos/asf/httpcomponents-client/blob/f1f3a387/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheEntryUpdater.java
----------------------------------------------------------------------
diff --git a/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheEntryUpdater.java b/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheEntryUpdater.java
index a745010..ed02ce5 100644
--- a/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheEntryUpdater.java
+++ b/httpclient-cache/src/test/java/org/apache/http/impl/client/cache/TestCacheEntryUpdater.java
@@ -239,6 +239,26 @@ public class TestCacheEntryUpdater {
         }
     }
 
+    @Test
+    public void testContentEncodingHeaderIsNotUpdatedByMerge() throws IOException {
+        final Header[] headers = {
+                new BasicHeader("Date", DateUtils.formatDate(requestDate)),
+                new BasicHeader("ETag", "\"etag\""),
+                new BasicHeader("Content-Encoding", "identity")};
+
+        entry = HttpTestUtils.makeCacheEntry(headers);
+        response.setHeaders(new Header[]{
+                new BasicHeader("Last-Modified", DateUtils.formatDate(responseDate)),
+                new BasicHeader("Cache-Control", "public"),
+                new BasicHeader("Content-Encoding", "gzip")});
+
+        final HttpCacheEntry updatedEntry = impl.updateCacheEntry(null, entry,
+                new Date(), new Date(), response);
+
+        final Header[] updatedHeaders = updatedEntry.getAllHeaders();
+        headersContain(updatedHeaders, "Content-Encoding", "identity");
+    }
+
     private void headersContain(final Header[] headers, final String name, final String value) {
         for (final Header header : headers) {
             if (header.getName().equals(name)) {