/* * Copyright 2013-2015 the original author or authors. * * Licensed 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. */ package org.springframework.cloud.netflix.zuul.filters; import java.io.IOException; import java.util.List; import org.junit.Before; import org.junit.Test; 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.http.MediaType; 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; import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.REQUEST_URI_KEY; /** * @author Spencer Gibb */ public class ProxyRequestHelperTests { @Mock private TraceRepository traceRepository; @Before public void init() { initMocks(this); } @Before public void setTestRequestcontext() { RequestContext context = new RequestContext(); RequestContext.testSetCurrentContext(context); } @Test public void debug() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); request.setContent("{}".getBytes()); request.addHeader("singleName", "singleValue"); request.addHeader("multiName", "multiValue1"); request.addHeader("multiName", "multiValue2"); RequestContext.getCurrentContext().setRequest(request); TraceProxyRequestHelper helper = new TraceProxyRequestHelper(); this.traceRepository = new InMemoryTraceRepository(); helper.setTraces(this.traceRepository); MultiValueMap<String, String> headers = helper.buildZuulRequestHeaders(request); helper.debug("POST", "http://example.com", headers, 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("{}")); } @Test public void shouldDebugBodyDisabled() throws Exception { RequestContext context = RequestContext.getCurrentContext(); ProxyRequestHelper helper = new ProxyRequestHelper(); helper.setTraceRequestBody(false); assertThat("shouldDebugBody wrong", helper.shouldDebugBody(context), is(false)); } @Test public void shouldDebugBodyChunked() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); RequestContext context = RequestContext.getCurrentContext(); context.setChunkedRequestBody(); context.setRequest(request); ProxyRequestHelper helper = new ProxyRequestHelper(); assertThat("shouldDebugBody wrong", helper.shouldDebugBody(context), is(false)); } @Test public void shouldDebugBodyServlet() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); RequestContext context = RequestContext.getCurrentContext(); context.setZuulEngineRan(); context.setRequest(request); ProxyRequestHelper helper = new ProxyRequestHelper(); assertThat("shouldDebugBody wrong", helper.shouldDebugBody(context), is(false)); } @Test public void shouldDebugBodyNullContentType() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); request.setContentType(null); RequestContext context = RequestContext.getCurrentContext(); context.setRequest(request); ProxyRequestHelper helper = new ProxyRequestHelper(); assertThat("shouldDebugBody wrong", helper.shouldDebugBody(context), is(true)); } @Test public void shouldDebugBodyNullRequest() throws Exception { RequestContext context = RequestContext.getCurrentContext(); ProxyRequestHelper helper = new ProxyRequestHelper(); assertThat("shouldDebugBody wrong", helper.shouldDebugBody(context), is(true)); } @Test public void shouldDebugBodyNotMultitypeContentType() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); request.setContentType(MediaType.APPLICATION_JSON_VALUE); RequestContext context = RequestContext.getCurrentContext(); context.setRequest(request); ProxyRequestHelper helper = new ProxyRequestHelper(); assertThat("shouldDebugBody wrong", helper.shouldDebugBody(context), is(true)); } @Test public void shouldDebugBodyMultitypeContentType() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); request.setContentType(MediaType.MULTIPART_FORM_DATA_VALUE); RequestContext context = RequestContext.getCurrentContext(); context.setRequest(request); ProxyRequestHelper helper = new ProxyRequestHelper(); assertThat("shouldDebugBody wrong", helper.shouldDebugBody(context), is(false)); } @Test public void buildZuulRequestHeadersWork() { MockHttpServletRequest request = new MockHttpServletRequest("GET", "/"); request.addHeader("singleName", "singleValue"); request.addHeader("multiName", "multiValue1"); request.addHeader("multiName", "multiValue2"); TraceProxyRequestHelper helper = new TraceProxyRequestHelper(); helper.setTraces(this.traceRepository); MultiValueMap<String, String> headers = helper.buildZuulRequestHeaders(request); List<String> singleName = headers.get("singleName"); assertThat(singleName, is(notNullValue())); assertThat(singleName.size(), is(1)); List<String> multiName = headers.get("multiName"); assertThat(multiName, is(notNullValue())); assertThat(multiName.size(), is(2)); List<String> missingName = headers.get("missingName"); assertThat(missingName, is(nullValue())); } @Test public void buildZuulRequestHeadersRequestsGzipAndOnlyGzip() { MockHttpServletRequest request = new MockHttpServletRequest("", "/"); ProxyRequestHelper helper = new ProxyRequestHelper(); MultiValueMap<String, String> headers = helper.buildZuulRequestHeaders(request); List<String> acceptEncodings = headers.get("accept-encoding"); assertThat(acceptEncodings, hasSize(1)); 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()); } @Test public void getQueryString() { MultiValueMap<String, String> params = new LinkedMultiValueMap<>(); params.add("a", "1234"); params.add("b", "5678"); String queryString = new ProxyRequestHelper().getQueryString(params); assertThat(queryString, is("?a=1234&b=5678")); } @Test public void getQueryStringWithEmptyParam() { MultiValueMap<String, String> params = new LinkedMultiValueMap<>(); params.add("wsdl", ""); String queryString = new ProxyRequestHelper().getQueryString(params); assertThat(queryString, is("?wsdl")); } @Test public void getQueryStringEncoded() { MultiValueMap<String, String> params = new LinkedMultiValueMap<>(); params.add("foo", "weird#chars"); String queryString = new ProxyRequestHelper().getQueryString(params); assertThat(queryString, is("?foo=weird%23chars")); } @Test public void getQueryParamNameWithColon() { MultiValueMap<String, String> params = new LinkedMultiValueMap<>(); params.add("foo:bar", "baz"); params.add("foobar", "bam"); params.add("foo\fbar", "bat"); // form feed is the colon replacement char String queryString = new ProxyRequestHelper().getQueryString(params); assertThat(queryString, is("?foo:bar=baz&foobar=bam&foo%0Cbar=bat")); } @Test public void buildZuulRequestURIWithUTF8() throws Exception { String encodedURI = "/resource/esp%C3%A9cial-char"; String decodedURI = "/resource/espécial-char"; MockHttpServletRequest request = new MockHttpServletRequest("GET", encodedURI); request.setCharacterEncoding("UTF-8"); final RequestContext context = RequestContext.getCurrentContext(); context.setRequest(request); context.set(REQUEST_URI_KEY, decodedURI); final String requestURI = new ProxyRequestHelper().buildZuulRequestURI(request); assertThat(requestURI, equalTo(encodedURI)); } @Test public void buildZuulRequestURIWithDefaultEncoding() { String encodedURI = "/resource/esp%E9cial-char"; String decodedURI = "/resource/espécial-char"; MockHttpServletRequest request = new MockHttpServletRequest("GET", encodedURI); final RequestContext context = RequestContext.getCurrentContext(); context.setRequest(request); context.set(REQUEST_URI_KEY, decodedURI); final String requestURI = new ProxyRequestHelper().buildZuulRequestURI(request); assertThat(requestURI, equalTo(encodedURI)); } @Test public void getUTF8Url() { String requestURI = "/oléדרעק"; String encodedRequestURI = "/ol%C3%A9%D7%93%D7%A8%D7%A2%D7%A7"; MockHttpServletRequest request = new MockHttpServletRequest("GET", requestURI); request.setCharacterEncoding("UTF-8"); RequestContext context = RequestContext.getCurrentContext(); context.set(REQUEST_URI_KEY, requestURI); ProxyRequestHelper helper = new ProxyRequestHelper(); String uri = helper.buildZuulRequestURI(request); assertThat(uri, is(encodedRequestURI)); } @Test public void getDefaultEncodingUrl() { String requestURI = "/oléדרעק"; String encodedRequestURI = "/ol%E9%3F%3F%3F%3F"; MockHttpServletRequest request = new MockHttpServletRequest("GET", requestURI); RequestContext context = RequestContext.getCurrentContext(); context.set(REQUEST_URI_KEY, requestURI); ProxyRequestHelper helper = new ProxyRequestHelper(); String uri = helper.buildZuulRequestURI(request); assertThat(uri, is(encodedRequestURI)); } }