Skip to content

Commit 1d86fde

Browse files
authored
SigV4a: Add host header only when not already provided (#6310)
* SigV4a: Add host header only when not already provided * Added change logs
1 parent eba1843 commit 1d86fde

File tree

3 files changed

+41
-6
lines changed

3 files changed

+41
-6
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"type": "feature",
3+
"category": "AWS SDK for Java v2",
4+
"contributor": "",
5+
"description": "Fixed SigV4a signing to respect pre-existing Host headers to be consistent with existing SigV4 signing behavior."
6+
}

core/http-auth-aws/src/main/java/software/amazon/awssdk/http/auth/aws/crt/internal/util/CrtUtils.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import static software.amazon.awssdk.http.auth.aws.internal.signer.util.SignerConstant.X_AMZ_SIGNED_HEADERS;
2626

2727
import java.nio.charset.StandardCharsets;
28+
import java.util.Optional;
2829
import java.util.Set;
2930
import java.util.TreeSet;
3031
import java.util.stream.Collectors;
@@ -56,7 +57,7 @@ private CrtUtils() {
5657
* Sanitize an {@link SdkHttpRequest}, in order to prepare it for converting to a CRT request destined to be signed.
5758
* <p>
5859
* Sanitizing includes checking the path is not empty, filtering headers and query parameters that are forbidden in CRT, and
59-
* adding the host header (overriding if already presesnt).
60+
* adding the host header
6061
*/
6162
public static SdkHttpRequest sanitizeRequest(SdkHttpRequest request) {
6263

@@ -77,11 +78,17 @@ public static SdkHttpRequest sanitizeRequest(SdkHttpRequest request) {
7778
}
7879
});
7980

80-
// Add host, which must be signed. We ignore any pre-existing Host header to match the behavior of the SigV4 signer.
81-
String hostHeader = SdkHttpUtils.isUsingStandardPort(request.protocol(), request.port())
82-
? request.host()
83-
: request.host() + ":" + request.port();
84-
builder.putHeader(HOST, hostHeader);
81+
// Add host header, which must be signed. If the SdkHttpRequest has an associated Host header
82+
// already set, prefer to use that.
83+
Optional<String> existingHostHeader = request.firstMatchingHeader(HOST);
84+
if (existingHostHeader.isPresent()) {
85+
builder.putHeader(HOST, existingHostHeader.get());
86+
} else {
87+
String hostHeader = SdkHttpUtils.isUsingStandardPort(request.protocol(), request.port())
88+
? request.host()
89+
: request.host() + ":" + request.port();
90+
builder.putHeader(HOST, hostHeader);
91+
}
8592

8693
builder.clearQueryParameters();
8794

core/http-auth-aws/src/test/java/software/amazon/awssdk/http/auth/aws/crt/internal/signer/DefaultAwsCrtV4aHttpSignerTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,4 +412,26 @@ public void sign_checksumValueProvided_shouldNotOverrideChecksumHeader() {
412412
assertThat(signedRequest.request().firstMatchingHeader("x-amz-checksum-crc32"))
413413
.contains("some value");
414414
}
415+
416+
@Test
417+
public void sign_withProvidedHostHeader_shouldRespectUserHostHeader() {
418+
AwsCredentialsIdentity credentials =
419+
AwsCredentialsIdentity.create("access", "secret");
420+
421+
String hostOverride = "virtual-host.localhost";
422+
SignRequest<AwsCredentialsIdentity> request = generateBasicRequest(
423+
credentials,
424+
httpRequest -> httpRequest.putHeader("Host", hostOverride).port(443),
425+
signRequest -> {
426+
427+
}
428+
);
429+
430+
SignedRequest signedRequest = signer.sign(request);
431+
432+
assertThat(signedRequest.request().firstMatchingHeader("Host")).hasValue(hostOverride);
433+
assertThat(signedRequest.request().firstMatchingHeader("X-Amz-Date")).hasValue("20200803T174823Z");
434+
assertThat(signedRequest.request().firstMatchingHeader("X-Amz-Region-Set")).hasValue("aws-global");
435+
assertThat(signedRequest.request().firstMatchingHeader("Authorization")).isPresent();
436+
}
415437
}

0 commit comments

Comments
 (0)