Commit 9891eb54 authored by Stephane Nicoll's avatar Stephane Nicoll

Merge pull request #6018 from venilnoronha:issue-5982-fix

* pr/6018:
  Polish "Add ability to filter cookies in trace data"
  Add ability to filter cookies in trace data
parents 0de5988c 84b2ff5c
/* /*
* Copyright 2012-2015 the original author or authors. * Copyright 2012-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -28,6 +28,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties; ...@@ -28,6 +28,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
* *
* @author Wallace Wadge * @author Wallace Wadge
* @author Phillip Webb * @author Phillip Webb
* @author Venil Noronha
* @since 1.3.0 * @since 1.3.0
*/ */
@ConfigurationProperties(prefix = "management.trace") @ConfigurationProperties(prefix = "management.trace")
...@@ -39,12 +40,14 @@ public class TraceProperties { ...@@ -39,12 +40,14 @@ public class TraceProperties {
Set<Include> defaultIncludes = new LinkedHashSet<Include>(); Set<Include> defaultIncludes = new LinkedHashSet<Include>();
defaultIncludes.add(Include.REQUEST_HEADERS); defaultIncludes.add(Include.REQUEST_HEADERS);
defaultIncludes.add(Include.RESPONSE_HEADERS); defaultIncludes.add(Include.RESPONSE_HEADERS);
defaultIncludes.add(Include.COOKIES);
defaultIncludes.add(Include.ERRORS); defaultIncludes.add(Include.ERRORS);
DEFAULT_INCLUDES = Collections.unmodifiableSet(defaultIncludes); DEFAULT_INCLUDES = Collections.unmodifiableSet(defaultIncludes);
} }
/** /**
* Items to be included in the trace. Defaults to request/response headers and errors. * Items to be included in the trace. Defaults to request/response headers (including cookies)
* and errors.
*/ */
private Set<Include> include = new HashSet<Include>(DEFAULT_INCLUDES); private Set<Include> include = new HashSet<Include>(DEFAULT_INCLUDES);
...@@ -71,6 +74,11 @@ public class TraceProperties { ...@@ -71,6 +74,11 @@ public class TraceProperties {
*/ */
RESPONSE_HEADERS, RESPONSE_HEADERS,
/**
* Include "Cookie" in request and "Set-Cookie" in response headers.
*/
COOKIES,
/** /**
* Include errors (if any). * Include errors (if any).
*/ */
......
...@@ -48,6 +48,7 @@ import org.springframework.web.filter.OncePerRequestFilter; ...@@ -48,6 +48,7 @@ import org.springframework.web.filter.OncePerRequestFilter;
* @author Dave Syer * @author Dave Syer
* @author Wallace Wadge * @author Wallace Wadge
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Venil Noronha
*/ */
public class WebRequestTraceFilter extends OncePerRequestFilter implements Ordered { public class WebRequestTraceFilter extends OncePerRequestFilter implements Ordered {
...@@ -162,6 +163,9 @@ public class WebRequestTraceFilter extends OncePerRequestFilter implements Order ...@@ -162,6 +163,9 @@ public class WebRequestTraceFilter extends OncePerRequestFilter implements Order
} }
headers.put(name, value); headers.put(name, value);
} }
if (!isIncluded(Include.COOKIES)) {
headers.remove("Cookie");
}
return headers; return headers;
} }
...@@ -179,6 +183,9 @@ public class WebRequestTraceFilter extends OncePerRequestFilter implements Order ...@@ -179,6 +183,9 @@ public class WebRequestTraceFilter extends OncePerRequestFilter implements Order
String value = response.getHeader(header); String value = response.getHeader(header);
headers.put(header, value); headers.put(header, value);
} }
if (!isIncluded(Include.COOKIES)) {
headers.remove("Set-Cookie");
}
headers.put("status", "" + response.getStatus()); headers.put("status", "" + response.getStatus());
return headers; return headers;
} }
......
...@@ -28,7 +28,6 @@ import javax.servlet.FilterChain; ...@@ -28,7 +28,6 @@ import javax.servlet.FilterChain;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import org.junit.Test; import org.junit.Test;
...@@ -50,6 +49,8 @@ import static org.mockito.Mockito.verify; ...@@ -50,6 +49,8 @@ import static org.mockito.Mockito.verify;
* @author Wallace Wadge * @author Wallace Wadge
* @author Phillip Webb * @author Phillip Webb
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Venil Noronha
* @author Stephane Nicoll
*/ */
public class WebRequestTraceFilterTests { public class WebRequestTraceFilterTests {
...@@ -79,6 +80,7 @@ public class WebRequestTraceFilterTests { ...@@ -79,6 +80,7 @@ public class WebRequestTraceFilterTests {
this.properties.setInclude(EnumSet.allOf(Include.class)); this.properties.setInclude(EnumSet.allOf(Include.class));
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo"); MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
request.addHeader("Accept", "application/json"); request.addHeader("Accept", "application/json");
request.addHeader("Cookie", "testCookie=testValue;");
request.setContextPath("some.context.path"); request.setContextPath("some.context.path");
request.setContent("Hello, World!".getBytes()); request.setContent("Hello, World!".getBytes());
request.setRemoteAddr("some.remote.addr"); request.setRemoteAddr("some.remote.addr");
...@@ -88,8 +90,6 @@ public class WebRequestTraceFilterTests { ...@@ -88,8 +90,6 @@ public class WebRequestTraceFilterTests {
String url = tmp.toURI().toURL().toString(); String url = tmp.toURI().toURL().toString();
request.setPathInfo(url); request.setPathInfo(url);
tmp.deleteOnExit(); tmp.deleteOnExit();
Cookie cookie = new Cookie("testCookie", "testValue");
request.setCookies(cookie);
request.setAuthType("authType"); request.setAuthType("authType");
Principal principal = new Principal() { Principal principal = new Principal() {
...@@ -102,6 +102,7 @@ public class WebRequestTraceFilterTests { ...@@ -102,6 +102,7 @@ public class WebRequestTraceFilterTests {
request.setUserPrincipal(principal); request.setUserPrincipal(principal);
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
response.addHeader("Content-Type", "application/json"); response.addHeader("Content-Type", "application/json");
response.addHeader("Set-Cookie", "a=b");
this.filter.doFilterInternal(request, response, new FilterChain() { this.filter.doFilterInternal(request, response, new FilterChain() {
@Override @Override
...@@ -120,7 +121,7 @@ public class WebRequestTraceFilterTests { ...@@ -120,7 +121,7 @@ public class WebRequestTraceFilterTests {
Map<String, Object> map = (Map<String, Object>) trace.get("headers"); Map<String, Object> map = (Map<String, Object>) trace.get("headers");
assertThat(map.get("response").toString()) assertThat(map.get("response").toString())
.isEqualTo("{Content-Type=application/json, status=200}"); .isEqualTo("{Content-Type=application/json, Set-Cookie=a=b, status=200}");
assertThat(trace.get("method")).isEqualTo("GET"); assertThat(trace.get("method")).isEqualTo("GET");
assertThat(trace.get("path")).isEqualTo("/foo"); assertThat(trace.get("path")).isEqualTo("/foo");
assertThat(((String[]) ((Map) trace.get("parameters")).get("param"))[0]) assertThat(((String[]) ((Map) trace.get("parameters")).get("param"))[0])
...@@ -131,7 +132,8 @@ public class WebRequestTraceFilterTests { ...@@ -131,7 +132,8 @@ public class WebRequestTraceFilterTests {
assertThat(trace.get("contextPath")).isEqualTo("some.context.path"); assertThat(trace.get("contextPath")).isEqualTo("some.context.path");
assertThat(trace.get("pathInfo")).isEqualTo(url); assertThat(trace.get("pathInfo")).isEqualTo(url);
assertThat(trace.get("authType")).isEqualTo("authType"); assertThat(trace.get("authType")).isEqualTo("authType");
assertThat(map.get("request").toString()).isEqualTo("{Accept=application/json}"); assertThat(map.get("request").toString())
.isEqualTo("{Accept=application/json, Cookie=testCookie=testValue;}");
} }
@Test @Test
...@@ -153,6 +155,35 @@ public class WebRequestTraceFilterTests { ...@@ -153,6 +155,35 @@ public class WebRequestTraceFilterTests {
assertThat(headers.get("response") == null).isTrue(); assertThat(headers.get("response") == null).isTrue();
} }
@Test
@SuppressWarnings({ "unchecked" })
public void filterDoesNotAddRequestCookiesWithCookiesExclude()
throws ServletException, IOException {
this.properties.setInclude(Collections.singleton(Include.REQUEST_HEADERS));
MockHttpServletRequest request = spy(new MockHttpServletRequest("GET", "/foo"));
request.addHeader("Accept", "application/json");
request.addHeader("Cookie", "testCookie=testValue;");
Map<String, Object> map = (Map<String, Object>) this.filter.getTrace(request)
.get("headers");
assertThat(map.get("request").toString()).isEqualTo("{Accept=application/json}");
}
@Test
@SuppressWarnings({ "unchecked" })
public void filterDoesNotAddResponseCookiesWithCookiesExclude()
throws ServletException, IOException {
this.properties.setInclude(Collections.singleton(Include.RESPONSE_HEADERS));
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
MockHttpServletResponse response = new MockHttpServletResponse();
response.addHeader("Content-Type", "application/json");
response.addHeader("Set-Cookie", "testCookie=testValue;");
Map<String, Object> trace = this.filter.getTrace(request);
this.filter.enhanceTrace(trace, response);
Map<String, Object> map = (Map<String, Object>) trace.get("headers");
assertThat(map.get("response").toString())
.isEqualTo("{Content-Type=application/json, status=200}");
}
@Test @Test
public void filterHasResponseStatus() { public void filterHasResponseStatus() {
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo"); MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
......
...@@ -1072,7 +1072,7 @@ content into your application; rather pick only the properties that you need. ...@@ -1072,7 +1072,7 @@ content into your application; rather pick only the properties that you need.
management.shell.telnet.port=5000 # Telnet port. management.shell.telnet.port=5000 # Telnet port.
# TRACING ({sc-spring-boot-actuator}/trace/TraceProperties.{sc-ext}[TraceProperties]) # TRACING ({sc-spring-boot-actuator}/trace/TraceProperties.{sc-ext}[TraceProperties])
management.trace.include=request-headers,response-headers,errors # Items to be included in the trace. management.trace.include=request-headers,response-headers,cookies,errors # Items to be included in the trace.
# METRICS EXPORT ({sc-spring-boot-actuator}/metrics/export/MetricExportProperties.{sc-ext}[MetricExportProperties]) # METRICS EXPORT ({sc-spring-boot-actuator}/metrics/export/MetricExportProperties.{sc-ext}[MetricExportProperties])
spring.metrics.export.aggregate.key-pattern= # Pattern that tells the aggregator what to do with the keys from the source repository. spring.metrics.export.aggregate.key-pattern= # Pattern that tells the aggregator what to do with the keys from the source repository.
......
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