Commit f707e5f0 by Jettro Coenradie Committed by Spencer Gibb

Case insensitive Content-Encoding check

Fixes a problem with a header in the response containing content-encoding in lowercase letters. Uses HttpHeaders for case insensitve check. Also fixes an issue checking if a request is made for gzip content. If headers has more than gzip (ie gzip,deflate,sdch), checks if contains gzip instead of equals to. Fixes gh-662
parent a61c18c6
......@@ -43,6 +43,9 @@ import com.netflix.zuul.util.HTTPRequestUtils;
import lombok.extern.apachecommons.CommonsLog;
import static org.springframework.http.HttpHeaders.CONTENT_ENCODING;
import static org.springframework.http.HttpHeaders.CONTENT_LENGTH;
/**
* @author Dave Syer
*/
......@@ -55,8 +58,6 @@ public class ProxyRequestHelper {
*/
public static final String IGNORED_HEADERS = "ignoredHeaders";
public static final String CONTENT_ENCODING = "Content-Encoding";
private TraceRepository traces;
public void setTraces(TraceRepository traces) {
......@@ -122,15 +123,23 @@ public class ProxyRequestHelper {
}
public void setResponse(int status, InputStream entity,
MultiValueMap<String, String> headers) throws IOException {
MultiValueMap<String, String> headers) throws IOException {
RequestContext context = RequestContext.getCurrentContext();
RequestContext.getCurrentContext().setResponseStatusCode(status);
context.setResponseStatusCode(status);
if (entity != null) {
RequestContext.getCurrentContext().setResponseDataStream(entity);
context.setResponseDataStream(entity);
}
HttpHeaders httpHeaders = new HttpHeaders();
for (Entry<String, List<String>> header : headers.entrySet()) {
List<String> values = header.getValue();
for (String value : values) {
httpHeaders.add(header.getKey(), value);
}
}
boolean isOriginResponseGzipped = false;
if (headers.containsKey(CONTENT_ENCODING)) {
Collection<String> collection = headers.get(CONTENT_ENCODING);
if (httpHeaders.containsKey(CONTENT_ENCODING)) {
List<String> collection = httpHeaders.get(CONTENT_ENCODING);
for (String header : collection) {
if (HTTPRequestUtils.getInstance().isGzipped(header)) {
isOriginResponseGzipped = true;
......@@ -139,16 +148,16 @@ public class ProxyRequestHelper {
}
}
context.setResponseGZipped(isOriginResponseGzipped);
for (Entry<String, List<String>> header : headers.entrySet()) {
RequestContext ctx = RequestContext.getCurrentContext();
String name = header.getKey();
for (String value : header.getValue()) {
ctx.addOriginResponseHeader(name, value);
if (name.equalsIgnoreCase("content-length")) {
ctx.setOriginContentLength(value);
context.addOriginResponseHeader(name, value);
if (name.equalsIgnoreCase(CONTENT_LENGTH)) {
context.setOriginContentLength(value);
}
if (isIncludedHeader(name)) {
ctx.addZuulResponseHeader(name, value);
context.addZuulResponseHeader(name, value);
}
}
}
......@@ -176,21 +185,21 @@ public class ProxyRequestHelper {
}
}
switch (name) {
case "host":
case "connection":
case "content-length":
case "content-encoding":
case "server":
case "transfer-encoding":
return false;
default:
return true;
case "host":
case "connection":
case "content-length":
case "content-encoding":
case "server":
case "transfer-encoding":
return false;
default:
return true;
}
}
public Map<String, Object> debug(String verb, String uri,
MultiValueMap<String, String> headers, MultiValueMap<String, String> params,
InputStream requestEntity) throws IOException {
MultiValueMap<String, String> headers, MultiValueMap<String, String> params,
InputStream requestEntity) throws IOException {
Map<String, Object> info = new LinkedHashMap<String, Object>();
if (this.traces != null) {
RequestContext context = RequestContext.getCurrentContext();
......@@ -233,7 +242,7 @@ public class ProxyRequestHelper {
}
public void appendDebug(Map<String, Object> info, int status,
MultiValueMap<String, String> headers) {
MultiValueMap<String, String> headers) {
if (this.traces != null) {
@SuppressWarnings("unchecked")
Map<String, Object> trace = (Map<String, Object>) info.get("headers");
......@@ -267,3 +276,4 @@ public class ProxyRequestHelper {
}
}
......@@ -22,7 +22,6 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.zip.GZIPInputStream;
import javax.servlet.http.HttpServletResponse;
import org.springframework.util.ReflectionUtils;
......@@ -35,10 +34,14 @@ import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.constants.ZuulConstants;
import com.netflix.zuul.constants.ZuulHeaders;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.util.HTTPRequestUtils;
import lombok.extern.apachecommons.CommonsLog;
/**
* @author Spencer Gibb
*/
@CommonsLog
public class SendResponseFilter extends ZuulFilter {
private static DynamicBooleanProperty INCLUDE_DEBUG_HEADER = DynamicPropertyFactory
......@@ -101,7 +104,9 @@ public class SendResponseFilter extends ZuulFilter {
boolean isGzipRequested = false;
final String requestEncoding = context.getRequest().getHeader(
ZuulHeaders.ACCEPT_ENCODING);
if (requestEncoding != null && requestEncoding.equals("gzip")) {
if (requestEncoding != null
&& HTTPRequestUtils.getInstance().isGzipped(requestEncoding)) {
isGzipRequested = true;
}
is = context.getResponseDataStream();
......@@ -117,8 +122,8 @@ public class SendResponseFilter extends ZuulFilter {
inputStream = new GZIPInputStream(is);
}
catch (java.util.zip.ZipException ex) {
System.out.println("gzip expected but not "
+ "received assuming unencoded response"
log.debug("gzip expected but not "
+ "received assuming unencoded response "
+ RequestContext.getCurrentContext().getRequest()
.getRequestURL().toString());
inputStream = is;
......
......@@ -16,15 +16,7 @@
package org.springframework.cloud.netflix.zuul.filters;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.mockito.MockitoAnnotations.initMocks;
import java.io.IOException;
import java.util.List;
import org.junit.Before;
......@@ -33,12 +25,24 @@ import org.mockito.Mock;
import org.springframework.boot.actuate.trace.InMemoryTraceRepository;
import org.springframework.boot.actuate.trace.Trace;
import org.springframework.boot.actuate.trace.TraceRepository;
import org.springframework.http.HttpHeaders;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import com.netflix.zuul.context.RequestContext;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.MockitoAnnotations.initMocks;
/**
* @author Spencer Gibb
*/
......@@ -71,7 +75,7 @@ public class ProxyRequestHelperTests {
new LinkedMultiValueMap<String, String>(), request.getInputStream());
Trace actual = this.traceRepository.findAll().get(0);
System.err.println(actual.getInfo());
assertThat((String)actual.getInfo().get("body"), equalTo("{}"));
assertThat((String) actual.getInfo().get("body"), equalTo("{}"));
}
......@@ -112,4 +116,45 @@ public class ProxyRequestHelperTests {
assertThat(acceptEncodings, contains("gzip"));
}
@Test
public void setResponseLowercase() throws IOException {
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");
MockHttpServletResponse response = new MockHttpServletResponse();
RequestContext context = RequestContext.getCurrentContext();
context.setRequest(request);
context.setResponse(response);
ProxyRequestHelper helper = new ProxyRequestHelper();
MultiValueMap<String, String> headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_ENCODING.toLowerCase(), "gzip");
helper.setResponse(
200,
request.getInputStream(),
headers);
assertTrue(context.getResponseGZipped());
}
@Test
public void setResponseUppercase() throws IOException {
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");
MockHttpServletResponse response = new MockHttpServletResponse();
RequestContext context = RequestContext.getCurrentContext();
context.setRequest(request);
context.setResponse(response);
ProxyRequestHelper helper = new ProxyRequestHelper();
MultiValueMap<String, String> headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_ENCODING, "gzip");
helper.setResponse(
200,
request.getInputStream(),
headers);
assertTrue(context.getResponseGZipped());
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment