Skip to content

Commit

Permalink
Added support for protocol version
Browse files Browse the repository at this point in the history
This fixes #75
  • Loading branch information
whiskeysierra committed Apr 20, 2016
1 parent fd1779d commit fac68d2
Show file tree
Hide file tree
Showing 23 changed files with 130 additions and 39 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ Content-Type: application/json
"origin": "remote",
"type": "request",
"correlation": "2d66e4bc-9a0d-11e5-a84c-1f39510f0d6b",
"protocol": "HTTP/1.1",
"sender": "127.0.0.1",
"method": "GET",
"path": "http://example.org/test",
Expand All @@ -196,6 +197,7 @@ Content-Type: application/json
"origin": "local",
"type": "response",
"correlation": "2d66e4bc-9a0d-11e5-a84c-1f39510f0d6b",
"protocol": "HTTP/1.1",
"status": 200,
"headers": {
"Content-Type": ["text/plain"]
Expand All @@ -212,6 +214,7 @@ a JSON response body will **not** be escaped and represented as a string:
"origin": "local",
"type": "response",
"correlation": "2d66e4bc-9a0d-11e5-a84c-1f39510f0d6b",
"protocol": "HTTP/1.1",
"status": 200,
"headers": {
"Content-Type": ["application/json"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,15 @@

public interface BaseHttpMessage {

String getProtocolVersion();

Origin getOrigin();

ListMultimap<String, String> getHeaders();

String getContentType();

Charset getCharset();

Origin getOrigin();

class Headers {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,4 @@ static BodyObfuscator none() {
return (contentType, body) -> body;
}

// TODO a special BodyObfuscator that only works for application/x-www-form-urlencoded and delegates to a key-value
// based obfuscator + Query Parameters

}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public String format(final Precorrelation<HttpRequest> precorrelation) throws IO
}

private String formatRequestLine(final HttpRequest request) {
return String.format("%s %s HTTP/1.1", request.getMethod(), renderRequestUri(request));
return String.format("%s %s %s", request.getMethod(), renderRequestUri(request), request.getProtocolVersion());
}

private String renderRequestUri(HttpRequest request) {
Expand All @@ -58,7 +58,7 @@ public String format(final Correlation<HttpRequest, HttpResponse> correlation) t

private String formatStatusLine(final HttpResponse response) {
// TODO we are missing the reason phrase here, e.g. "OK", but there is no complete list in the JDK alone
return String.format("HTTP/1.1 %d", response.getStatus());
return String.format("%s %d", response.getProtocolVersion(), response.getStatus());
}

private <H extends HttpMessage> String format(final H message, final String type, final String correlationId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ public abstract class ForwardingHttpMessage extends ForwardingObject implements
@Override
protected abstract HttpMessage delegate();

@Override
public String getProtocolVersion() {
return delegate().getProtocolVersion();
}

@Override
public ListMultimap<String, String> getHeaders() {
return delegate().getHeaders();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ public ListMultimap<String, String> getQueryParameters() {
return delegate().getQueryParameters();
}

@Override
public String getProtocolVersion() {
return delegate().getProtocolVersion();
}

@Override
public HttpRequest withBody() throws IOException {
return delegate().withBody();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ public String format(final Precorrelation<HttpRequest> precorrelation) throws IO
builder.put("origin", translate(request.getOrigin()));
builder.put("type", "request");
builder.put("correlation", correlationId);
builder.put("protocol", request.getProtocolVersion());
builder.put("remote", request.getRemote());
builder.put("method", request.getMethod());
builder.put("uri", renderRequestUri(request));
Expand Down Expand Up @@ -91,6 +92,7 @@ public String format(final Correlation<HttpRequest, HttpResponse> correlation) t
builder.put("origin", translate(response.getOrigin()));
builder.put("type", "response");
builder.put("correlation", correlationId);
builder.put("protocol", response.getProtocolVersion());
builder.put("status", response.getStatus());
addUnless(builder, "headers", response.getHeaders().asMap(), Map::isEmpty);
addBody(response, builder);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public final class DefaultHttpLogFormatterTest {
public void shouldLogRequest() throws IOException {
final String correlationId = "c9408eaa-677d-11e5-9457-10ddb1ee7671";
final HttpRequest request = MockHttpRequest.builder()
.protocolVersion("HTTP/1.0")
.origin(Origin.REMOTE)
.requestUri("/test")
.queryParameters(ImmutableListMultimap.of(
Expand All @@ -52,7 +53,7 @@ public void shouldLogRequest() throws IOException {
final String http = unit.format(new SimplePrecorrelation<>(correlationId, request));

assertThat(http, equalTo("Incoming Request: c9408eaa-677d-11e5-9457-10ddb1ee7671\n" +
"GET /test?limit=1 HTTP/1.1\n" +
"GET /test?limit=1 HTTP/1.0\n" +
"Accept: application/json\n" +
"Content-Type: text/plain\n" +
"\n" +
Expand Down Expand Up @@ -101,6 +102,7 @@ public void shouldLogResponse() throws IOException {
final String correlationId = "2d51bc02-677e-11e5-8b9b-10ddb1ee7671";
final HttpRequest request = MockHttpRequest.create();
final HttpResponse response = MockHttpResponse.builder()
.protocolVersion("HTTP/1.0")
.origin(Origin.REMOTE)
.headers(ImmutableListMultimap.of("Content-Type", "application/json"))
.body("{\"success\":true}")
Expand All @@ -109,7 +111,7 @@ public void shouldLogResponse() throws IOException {
final String http = unit.format(new SimpleCorrelation<>(correlationId, request, response));

assertThat(http, equalTo("Incoming Response: 2d51bc02-677e-11e5-8b9b-10ddb1ee7671\n" +
"HTTP/1.1 200\n" +
"HTTP/1.0 200\n" +
"Content-Type: application/json\n" +
"\n" +
"{\"success\":true}"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public void shouldDelegate() throws IOException {
assertThat(unit.getMethod(), is("GET"));
assertThat(unit.getRequestUri(), is("http://localhost/"));
assertThat(unit.getQueryParameters().values(), is(empty()));
assertThat(unit.getProtocolVersion(), is("HTTP/1.1"));
assertThat(unit.getHeaders().values(), is(empty()));
assertThat(unit.getContentType(), is(""));
assertThat(unit.getCharset(), is(UTF_8));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public void shouldDelegate() throws IOException {
assertThat(unit.getMethod(), is("GET"));
assertThat(unit.getRequestUri(), is("http://localhost/"));
assertThat(unit.getQueryParameters().values(), is(empty()));
assertThat(unit.getProtocolVersion(), is("HTTP/1.1"));
assertThat(unit.getHeaders(), is(ImmutableMultimap.of()));
assertThat(unit.getContentType(), is(""));
assertThat(unit.getCharset(), is(UTF_8));
Expand All @@ -64,6 +65,7 @@ public void shouldDelegateWithBody() throws IOException {
assertThat(request.getMethod(), is("GET"));
assertThat(request.getRequestUri(), is("http://localhost/"));
assertThat(request.getQueryParameters().values(), is(empty()));
assertThat(request.getProtocolVersion(), is("HTTP/1.1"));
assertThat(request.getHeaders().values(), is(empty()));
assertThat(request.getContentType(), is(""));
assertThat(request.getCharset(), is(UTF_8));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public final class JsonHttpLogFormatterTest {
public void shouldLogRequest() throws IOException {
final String correlationId = "3ce91230-677b-11e5-87b7-10ddb1ee7671";
final HttpRequest request = MockHttpRequest.builder()
.protocolVersion("HTTP/1.0")
.origin(REMOTE)
.requestUri("/test")
.queryParameters(ImmutableListMultimap.of(
Expand All @@ -65,6 +66,7 @@ public void shouldLogRequest() throws IOException {
.assertThat("$.origin", is("remote"))
.assertThat("$.type", is("request"))
.assertThat("$.correlation", is("3ce91230-677b-11e5-87b7-10ddb1ee7671"))
.assertThat("$.protocol", is("HTTP/1.0"))
.assertThat("$.remote", is("127.0.0.1"))
.assertThat("$.method", is("GET"))
.assertThat("$.uri", is("/test?limit=1"))
Expand Down Expand Up @@ -188,6 +190,7 @@ public void shouldLogResponse() throws IOException {
final String correlationId = "53de2640-677d-11e5-bc84-10ddb1ee7671";
final HttpRequest request = MockHttpRequest.create();
final HttpResponse response = MockHttpResponse.builder()
.protocolVersion("HTTP/1.0")
.origin(LOCAL)
.headers(ImmutableListMultimap.of("Date", "Tue, 15 Nov 1994 08:12:31 GMT"))
.contentType("application/xml")
Expand All @@ -200,6 +203,7 @@ public void shouldLogResponse() throws IOException {
.assertThat("$.origin", is("local"))
.assertThat("$.type", is("response"))
.assertThat("$.correlation", is("53de2640-677d-11e5-bc84-10ddb1ee7671"))
.assertThat("$.protocol", is("HTTP/1.0"))
.assertThat("$.status", is(200))
.assertThat("$.headers.*", hasSize(1))
.assertThat("$.headers['Date']", is(singletonList("Tue, 15 Nov 1994 08:12:31 GMT")))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,4 @@ public void shouldRenderInOrder() {
assertThat(render(of("c", "3", "d", "4", "a", "1", "e", "5", "b", "2")), is("c=3&d=4&a=1&e=5&b=2"));
}

// TODO test decode/encode

}
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ public Origin getOrigin() {
return Origin.LOCAL;
}

@Override
public String getProtocolVersion() {
return request.getRequestLine().getProtocolVersion().toString();
}

@Override
public String getRemote() {
try {
Expand All @@ -95,17 +100,17 @@ public String getMethod() {
@Override
public String getRequestUri() {
return stripQueryString(
originalRequestUri.getScheme(),
originalRequestUri.getUserInfo(),
originalRequestUri.getHost(),
originalRequestUri.getPort(),
originalRequestUri.getPath(),
originalRequestUri.getScheme(),
originalRequestUri.getUserInfo(),
originalRequestUri.getHost(),
originalRequestUri.getPort(),
originalRequestUri.getPath(),
originalRequestUri.getFragment());
}

@SneakyThrows
@VisibleForTesting
static String stripQueryString(final String scheme, final String userInfo, final String host, final int port,
static String stripQueryString(final String scheme, final String userInfo, final String host, final int port,
final String path, final String fragment) {
return new URI(scheme, userInfo, host, port, path, null, fragment).toASCIIString();
}
Expand All @@ -115,15 +120,15 @@ public ListMultimap<String, String> getQueryParameters() {
final ListMultimap<String, String> parameters = ArrayListMultimap.create();

@Nullable final String query = originalRequestUri.getRawQuery();

if (query == null) {
return ImmutableListMultimap.of();
}

for (NameValuePair pair : parse(query, UTF_8)) {
parameters.put(pair.getName(), pair.getValue());
}

return Multimaps.unmodifiableListMultimap(parameters);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ public Origin getOrigin() {
return Origin.REMOTE;
}

@Override
public String getProtocolVersion() {
return response.getStatusLine().getProtocolVersion().toString();
}

@Override
public int getStatus() {
return response.getStatusLine().getStatusCode();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,24 +49,31 @@ final class LocalResponse extends HttpServletResponseWrapper implements RawHttpR

private final TeeServletOutputStream stream;
private final PrintWriter writer;
private final String protocolVersion;

/**
* Null until we successfully intercepted it.
*/
@Nullable
private byte[] body;

LocalResponse(final HttpServletResponse response) throws IOException {
LocalResponse(final HttpServletResponse response, final String protocolVersion) throws IOException {
super(response);
this.stream = new TeeServletOutputStream();
this.writer = new TeePrintWriter();
this.protocolVersion = protocolVersion;
}

@Override
public Origin getOrigin() {
return Origin.LOCAL;
}

@Override
public String getProtocolVersion() {
return protocolVersion;
}

@Override
public ListMultimap<String, String> getHeaders() {
final ListMultimap<String, String> headers = Headers.create();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ public void doFilter(final Logbook logbook, final HttpServletRequest httpRequest
final Optional<Correlator> correlator = logRequestIfNecessary(logbook, request);

if (correlator.isPresent()) {
final LocalResponse response = new LocalResponse(httpResponse);
final String protocolVersion = request.getProtocolVersion();
final LocalResponse response = new LocalResponse(httpResponse, protocolVersion);

chain.doFilter(request, response);
response.getWriter().flush();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ final class RemoteRequest extends HttpServletRequestWrapper implements RawHttpRe
super(request);
}

@Override
public String getProtocolVersion() {
return getProtocol();
}

@Override
public Origin getOrigin() {
return Origin.REMOTE;
Expand All @@ -81,10 +86,10 @@ public String getRequestUri() {
@Override
public ListMultimap<String, String> getQueryParameters() {
final ListMultimap<String, String> parameters = ArrayListMultimap.create();
getParameterMap().forEach((name, values) ->

getParameterMap().forEach((name, values) ->
Collections.addAll(parameters.get(name), values));

return Multimaps.unmodifiableListMultimap(parameters);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ public void doFilter(final Logbook logbook, final HttpServletRequest httpRequest
final HttpServletResponse httpResponse, final FilterChain chain) throws ServletException, IOException {

final RemoteRequest request = new RemoteRequest(httpRequest);
final LocalResponse response = new LocalResponse(httpResponse);
final String protocolVersion = request.getProtocolVersion();
final LocalResponse response = new LocalResponse(httpResponse, protocolVersion);

chain.doFilter(request, response);

Expand Down
Loading

0 comments on commit fac68d2

Please sign in to comment.