Skip to content

Commit

Permalink
Handle header lists in URLConnection client
Browse files Browse the repository at this point in the history
  • Loading branch information
dagnir committed Feb 8, 2024
1 parent 4a81f88 commit 8477578
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 1 deletion.
6 changes: 6 additions & 0 deletions .changes/next-release/bugfix-URLConnectionClient-71a8135.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"type": "bugfix",
"category": "URL Connection Client",
"contributor": "",
"description": "Fix a bug where headers with multiple values don't have all values for that header sent on the wire. This leads to signature mismatch exceptions.\n\nFixes [#4746](https://github.com/aws/aws-sdk-java-v2/issues/4746)."
}
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ public String clientName() {
private HttpURLConnection createAndConfigureConnection(HttpExecuteRequest request) {
SdkHttpRequest sdkHttpRequest = request.httpRequest();
HttpURLConnection connection = connectionFactory.createConnection(sdkHttpRequest.getUri());
sdkHttpRequest.forEachHeader((key, values) -> values.forEach(value -> connection.setRequestProperty(key, value)));
setHeaders(connection, sdkHttpRequest);

// connection.setRequestProperty("Transfer-Encoding", "chunked") does not work, i.e., property does not get set
if (sdkHttpRequest.matchingHeaders("Transfer-Encoding").contains("chunked")) {
Expand Down Expand Up @@ -180,6 +180,13 @@ private HttpURLConnection createAndConfigureConnection(HttpExecuteRequest reques
return connection;
}

private void setHeaders(HttpURLConnection connection, SdkHttpRequest request) {
request.forEachHeader((name, values) -> {
String commaSeparated = String.join(",", values);
connection.addRequestProperty(name, commaSeparated);
});
}

private HttpURLConnection createDefaultConnection(URI uri, SSLSocketFactory socketFactory) {

Optional<Proxy> proxy = determineProxy(uri);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file 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 software.amazon.awssdk.http.urlconnection;

import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
import static com.github.tomakehurst.wiremock.client.WireMock.putRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;

import com.github.tomakehurst.wiremock.WireMockServer;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.Arrays;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import software.amazon.awssdk.http.ContentStreamProvider;
import software.amazon.awssdk.http.HttpExecuteRequest;
import software.amazon.awssdk.http.SdkHttpClient;
import software.amazon.awssdk.http.SdkHttpFullRequest;
import software.amazon.awssdk.http.SdkHttpMethod;

public class HeadersListTest {
private static final WireMockServer WIRE_MOCK = new WireMockServer(0);
private static SdkHttpClient client;

@BeforeAll
public static void setup() {
WIRE_MOCK.start();
client = UrlConnectionHttpClient.create();
}

@AfterAll
public static void teardown() {
client.close();
WIRE_MOCK.stop();
}

@Test
public void execute_requestHeaderHasMultipleValues_allValuesSent() throws IOException {
ContentStreamProvider provider = () -> new ByteArrayInputStream(new byte[0]);
SdkHttpFullRequest httpRequest = SdkHttpFullRequest.builder()
.method(SdkHttpMethod.PUT)
.host("localhost")
.port(WIRE_MOCK.port())
.protocol("http")
.putHeader("my-header", Arrays.asList("value1", "value2"))
.encodedPath("/test")
.build();

HttpExecuteRequest request = HttpExecuteRequest.builder()
.request(httpRequest)
.contentStreamProvider(provider)
.build();

client.prepareRequest(request).call();

WIRE_MOCK.verify(putRequestedFor(urlEqualTo("/test"))
.withHeader("my-header", equalTo("value1,value2")));
}
}

0 comments on commit 8477578

Please sign in to comment.