HTTPCLIENT-988: cache module should strip 'Content-Encoding: identity' from responses
Contributed by Jonathan Moore <jonathan_moore at comcast.com> git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@993497 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
ec40554d4d
commit
fb038d3500
|
@ -31,6 +31,7 @@ import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.http.Header;
|
import org.apache.http.Header;
|
||||||
|
import org.apache.http.HeaderElement;
|
||||||
import org.apache.http.HttpEntityEnclosingRequest;
|
import org.apache.http.HttpEntityEnclosingRequest;
|
||||||
import org.apache.http.HttpRequest;
|
import org.apache.http.HttpRequest;
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
|
@ -83,6 +84,8 @@ class ResponseProtocolCompliance {
|
||||||
|
|
||||||
ensure206ContainsDateHeader(response);
|
ensure206ContainsDateHeader(response);
|
||||||
|
|
||||||
|
identityIsNotUsedInContentEncoding(response);
|
||||||
|
|
||||||
warningsWithNonMatchingWarnDatesAreRemoved(response);
|
warningsWithNonMatchingWarnDatesAreRemoved(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,6 +119,35 @@ class ResponseProtocolCompliance {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void identityIsNotUsedInContentEncoding(HttpResponse response) {
|
||||||
|
Header[] hdrs = response.getHeaders("Content-Encoding");
|
||||||
|
if (hdrs == null || hdrs.length == 0) return;
|
||||||
|
List<Header> newHeaders = new ArrayList<Header>();
|
||||||
|
boolean modified = false;
|
||||||
|
for (Header h : hdrs) {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
boolean first = true;
|
||||||
|
for (HeaderElement elt : h.getElements()) {
|
||||||
|
if ("identity".equalsIgnoreCase(elt.getName())) {
|
||||||
|
modified = true;
|
||||||
|
} else {
|
||||||
|
if (!first) buf.append(",");
|
||||||
|
buf.append(elt.toString());
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String newHeaderValue = buf.toString();
|
||||||
|
if (!"".equals(newHeaderValue)) {
|
||||||
|
newHeaders.add(new BasicHeader("Content-Encoding", newHeaderValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!modified) return;
|
||||||
|
response.removeHeaders("Content-Encoding");
|
||||||
|
for (Header h : newHeaders) {
|
||||||
|
response.addHeader(h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void authenticationRequiredDidNotHaveAProxyAuthenticationHeader(HttpRequest request,
|
private void authenticationRequiredDidNotHaveAProxyAuthenticationHeader(HttpRequest request,
|
||||||
HttpResponse response) throws ClientProtocolException {
|
HttpResponse response) throws ClientProtocolException {
|
||||||
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED)
|
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED)
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package org.apache.http.impl.client.cache;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.apache.http.Header;
|
||||||
|
import org.apache.http.HeaderElement;
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This test class captures functionality required to achieve unconditional
|
||||||
|
* compliance with the HTTP/1.1 spec, i.e. all the SHOULD, SHOULD NOT,
|
||||||
|
* RECOMMENDED, and NOT RECOMMENDED behaviors.
|
||||||
|
*/
|
||||||
|
public class TestProtocolRecommendations extends AbstractProtocolTest {
|
||||||
|
|
||||||
|
/* "identity: The default (identity) encoding; the use of no
|
||||||
|
* transformation whatsoever. This content-coding is used only in the
|
||||||
|
* Accept-Encoding header, and SHOULD NOT be used in the
|
||||||
|
* Content-Encoding header."
|
||||||
|
*
|
||||||
|
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testIdentityCodingIsNotUsedInContentEncodingHeader()
|
||||||
|
throws Exception {
|
||||||
|
originResponse.setHeader("Content-Encoding", "identity");
|
||||||
|
backendExpectsAnyRequest().andReturn(originResponse);
|
||||||
|
replayMocks();
|
||||||
|
HttpResponse result = impl.execute(host, request);
|
||||||
|
verifyMocks();
|
||||||
|
boolean foundIdentity = false;
|
||||||
|
for(Header h : result.getHeaders("Content-Encoding")) {
|
||||||
|
for(HeaderElement elt : h.getElements()) {
|
||||||
|
if ("identity".equalsIgnoreCase(elt.getName())) {
|
||||||
|
foundIdentity = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertFalse(foundIdentity);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1354,7 +1354,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
|
||||||
originResponse.addHeader("Allow", "GET,HEAD");
|
originResponse.addHeader("Allow", "GET,HEAD");
|
||||||
originResponse.addHeader("Cache-Control", "max-age=3600");
|
originResponse.addHeader("Cache-Control", "max-age=3600");
|
||||||
originResponse.addHeader("Content-Language", "en");
|
originResponse.addHeader("Content-Language", "en");
|
||||||
originResponse.addHeader("Content-Encoding", "identity");
|
originResponse.addHeader("Content-Encoding", "x-coding");
|
||||||
originResponse.addHeader("Content-MD5", "Q2hlY2sgSW50ZWdyaXR5IQ==");
|
originResponse.addHeader("Content-MD5", "Q2hlY2sgSW50ZWdyaXR5IQ==");
|
||||||
originResponse.addHeader("Content-Length", "128");
|
originResponse.addHeader("Content-Length", "128");
|
||||||
originResponse.addHeader("Content-Type", "application/octet-stream");
|
originResponse.addHeader("Content-Type", "application/octet-stream");
|
||||||
|
@ -1401,7 +1401,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
|
||||||
originResponse.addHeader("Allow", "GET,HEAD");
|
originResponse.addHeader("Allow", "GET,HEAD");
|
||||||
originResponse.addHeader("Cache-Control", "max-age=3600");
|
originResponse.addHeader("Cache-Control", "max-age=3600");
|
||||||
originResponse.addHeader("Content-Language", "en");
|
originResponse.addHeader("Content-Language", "en");
|
||||||
originResponse.addHeader("Content-Encoding", "identity");
|
originResponse.addHeader("Content-Encoding", "x-coding");
|
||||||
originResponse.addHeader("Content-MD5", "Q2hlY2sgSW50ZWdyaXR5IQ==");
|
originResponse.addHeader("Content-MD5", "Q2hlY2sgSW50ZWdyaXR5IQ==");
|
||||||
originResponse.addHeader("Content-Length", "128");
|
originResponse.addHeader("Content-Length", "128");
|
||||||
originResponse.addHeader("Content-Type", "application/octet-stream");
|
originResponse.addHeader("Content-Type", "application/octet-stream");
|
||||||
|
@ -1425,7 +1425,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
|
||||||
Assert.assertEquals("GET,HEAD", result.getFirstHeader("Allow").getValue());
|
Assert.assertEquals("GET,HEAD", result.getFirstHeader("Allow").getValue());
|
||||||
Assert.assertEquals("max-age=3600", result.getFirstHeader("Cache-Control").getValue());
|
Assert.assertEquals("max-age=3600", result.getFirstHeader("Cache-Control").getValue());
|
||||||
Assert.assertEquals("en", result.getFirstHeader("Content-Language").getValue());
|
Assert.assertEquals("en", result.getFirstHeader("Content-Language").getValue());
|
||||||
Assert.assertEquals("identity", result.getFirstHeader("Content-Encoding").getValue());
|
Assert.assertEquals("x-coding", result.getFirstHeader("Content-Encoding").getValue());
|
||||||
Assert.assertEquals("Q2hlY2sgSW50ZWdyaXR5IQ==", result.getFirstHeader("Content-MD5")
|
Assert.assertEquals("Q2hlY2sgSW50ZWdyaXR5IQ==", result.getFirstHeader("Content-MD5")
|
||||||
.getValue());
|
.getValue());
|
||||||
Assert.assertEquals(originResponse.getFirstHeader("Last-Modified").getValue(), result
|
Assert.assertEquals(originResponse.getFirstHeader("Last-Modified").getValue(), result
|
||||||
|
@ -1873,7 +1873,7 @@ public class TestProtocolRequirements extends AbstractProtocolTest {
|
||||||
HttpResponse resp1 = make200Response();
|
HttpResponse resp1 = make200Response();
|
||||||
resp1.setHeader("ETag", "W/\"v1\"");
|
resp1.setHeader("ETag", "W/\"v1\"");
|
||||||
resp1.setHeader("Allow", "GET,HEAD");
|
resp1.setHeader("Allow", "GET,HEAD");
|
||||||
resp1.setHeader("Content-Encoding", "identity");
|
resp1.setHeader("Content-Encoding", "x-coding");
|
||||||
resp1.setHeader("Content-Language", "en");
|
resp1.setHeader("Content-Language", "en");
|
||||||
resp1.setHeader("Content-Length", "128");
|
resp1.setHeader("Content-Length", "128");
|
||||||
resp1.setHeader("Content-MD5", "Q2hlY2sgSW50ZWdyaXR5IQ==");
|
resp1.setHeader("Content-MD5", "Q2hlY2sgSW50ZWdyaXR5IQ==");
|
||||||
|
|
Loading…
Reference in New Issue