From 37519398c735dc4dca3c5f04bb0b309cd7b1dc19 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Thu, 23 Jun 2016 11:41:57 +0100 Subject: [PATCH] Include customized Host header in curl and HTTPie request snippets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, the curl and HTTPie request snippets always excluded the Host header, relying on the Host header that’s auto-generated by curl and HTTPie instead. This worked well for the most part, but meant that incorrect snippets were generated when the request was being sent with a custom host header that did not match the header that would be auto-generated. This commit updates CliOperationRequest to only filter out the Host header if it’s the same as the header that would be auto-generated by curl or HTTPie. Closes gh-258 --- .../restdocs/cli/CliOperationRequest.java | 49 ++++++++++++++----- .../restdocs/cli/CurlRequestSnippetTests.java | 14 ++++++ .../cli/HttpieRequestSnippetTests.java | 14 ++++++ 3 files changed, 66 insertions(+), 11 deletions(-) diff --git a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CliOperationRequest.java b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CliOperationRequest.java index 97d64c25..ce305278 100644 --- a/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CliOperationRequest.java +++ b/spring-restdocs-core/src/main/java/org/springframework/restdocs/cli/CliOperationRequest.java @@ -17,8 +17,8 @@ package org.springframework.restdocs.cli; import java.net.URI; +import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -41,20 +41,15 @@ import org.springframework.util.Base64Utils; */ final class CliOperationRequest implements OperationRequest { - private static final Set HEADER_FILTERS; - - static { - Set headerFilters = new HashSet<>(); - headerFilters.add(new NamedHeaderFilter(HttpHeaders.HOST)); - headerFilters.add(new NamedHeaderFilter(HttpHeaders.CONTENT_LENGTH)); - headerFilters.add(new BasicAuthHeaderFilter()); - HEADER_FILTERS = Collections.unmodifiableSet(headerFilters); - } + private final Set headerFilters; private final OperationRequest delegate; CliOperationRequest(OperationRequest delegate) { this.delegate = delegate; + this.headerFilters = new HashSet<>(Arrays.asList( + new NamedHeaderFilter(HttpHeaders.CONTENT_LENGTH), + new BasicAuthHeaderFilter(), new HostHeaderFilter(delegate.getUri()))); } Parameters getUniqueParameters() { @@ -121,11 +116,20 @@ final class CliOperationRequest implements OperationRequest { } private boolean allowedHeader(Map.Entry> header) { - for (HeaderFilter headerFilter : HEADER_FILTERS) { + for (HeaderFilter headerFilter : this.headerFilters) { if (!headerFilter.allow(header.getKey(), header.getValue())) { return false; } } + if (HttpHeaders.HOST.equalsIgnoreCase(header.getKey())) { + if (!header.getValue().isEmpty()) { + String value = header.getValue().get(0); + if (value.equals(this.delegate.getUri().getHost() + ":" + + this.delegate.getUri().getPort())) { + return false; + } + } + } return true; } @@ -187,4 +191,27 @@ final class CliOperationRequest implements OperationRequest { } + private static final class HostHeaderFilter implements HeaderFilter { + + private final URI uri; + + private HostHeaderFilter(URI uri) { + this.uri = uri; + } + + @Override + public boolean allow(String name, List value) { + if (value.isEmpty() || this.getImplicitHostHeader().equals(value.get(0))) { + return false; + } + return true; + } + + private String getImplicitHostHeader() { + return this.uri.getHost() + + ((this.uri.getPort() == -1) ? "" : ":" + this.uri.getPort()); + } + + } + } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/CurlRequestSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/CurlRequestSnippetTests.java index 86f5a04f..ba953fed 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/CurlRequestSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/CurlRequestSnippetTests.java @@ -330,4 +330,18 @@ public class CurlRequestSnippetTests extends AbstractSnippetTests { .request("http://localhost/foo").build()); } + @Test + public void customHostHeaderIsIncluded() throws IOException { + this.snippet.expectCurlRequest("custom-host-header") + .withContents(codeBlock("bash").content( + "$ curl 'http://localhost/foo' -i" + " -H 'Host: api.example.com'" + + " -H 'Content-Type: application/json' -H 'a: alpha'")); + new CurlRequestSnippet().document( + operationBuilder("custom-host-header").request("http://localhost/foo") + .header(HttpHeaders.HOST, "api.example.com") + .header(HttpHeaders.CONTENT_TYPE, + MediaType.APPLICATION_JSON_VALUE) + .header("a", "alpha").build()); + } + } diff --git a/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/HttpieRequestSnippetTests.java b/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/HttpieRequestSnippetTests.java index 8f9f48db..c3b9a398 100644 --- a/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/HttpieRequestSnippetTests.java +++ b/spring-restdocs-core/src/test/java/org/springframework/restdocs/cli/HttpieRequestSnippetTests.java @@ -332,4 +332,18 @@ public class HttpieRequestSnippetTests extends AbstractSnippetTests { .request("http://localhost/foo").build()); } + @Test + public void customHostHeaderIsIncluded() throws IOException { + this.snippet.expectHttpieRequest("custom-host-header") + .withContents(codeBlock("bash").content( + "$ http GET 'http://localhost/foo' 'Host:api.example.com'" + + " 'Content-Type:application/json' 'a:alpha'")); + new HttpieRequestSnippet().document( + operationBuilder("custom-host-header").request("http://localhost/foo") + .header(HttpHeaders.HOST, "api.example.com") + .header(HttpHeaders.CONTENT_TYPE, + MediaType.APPLICATION_JSON_VALUE) + .header("a", "alpha").build()); + } + }