aws-sdk-java-v2 icon indicating copy to clipboard operation
aws-sdk-java-v2 copied to clipboard

Unable to establish HTTP/2 connection to S3

Open bairamovazat opened this issue 1 year ago • 7 comments

Describe the bug

Fails to connect to S3 using HTTP/2.

Expected Behavior

AWS SDK v2 will establish an HTTP/2 connection

Current Behavior

I get an error when I try to send a request (any request):

software.amazon.awssdk.core.exception.SdkClientException: Unable to execute HTTP request: First received frame was not SETTINGS. Hex dump for first 5 bytes: 485454502f

Full response from S3:

HTTP/1.1 400 Bad Request Server: nginx Date: Wed, 18 Oct 2023 17:51:53 GMT Content-Type: text/html Content-Length: 150 Connection: close

Reproduction Steps

  1. Create a S3AsyncClient
 var client = S3AsyncClient.builder()
                .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(s3Config.getAccessKey(), s3Config.getSecretKey())))
                .region(Region.of(s3Config.getRegion()))
                .endpointOverride(endpointURI)
                .httpClient(NettyNioAsyncHttpClient.builder()
                        .protocol(Protocol.HTTP2)
                        .build())
                .build();
  1. Try to execute any request
var bucketAcl = client.getBucketAcl(GetBucketAclRequest.builder()
               .bucket(myBucket)
               .build());
var response = bucketAcl.join();

Possible Solution

No response

Additional Information/Context

I want to use an HTTP/2 connection to speed up the download of many small files. Right now the execution time of a request to retrieve a file is about 50 ms.

AWS Java SDK version used

2.21.1

JDK version used

openjdk 21.0.1 2023-10-17

Operating System and version

Window/Linux

bairamovazat avatar Oct 19 '23 14:10 bairamovazat

I tried testing HTTP/2 through curl. Сurl works fine :

curl --http2 -k -sI -w "@curl-format.txt" -s "https://S3_FQDN/PUBLIC_BACKET/FILE_NAME"
curl --http2-prior-knowledge -k -sI -w "@curl-format.txt" -s "https://S3_FQDN/PUBLIC_BACKET/FILE_NAME"

HTTP/2 200 server: nginx date: Fri, 20 Oct 2023 10:28:02 GMT content-type: application/octet-stream content-length: 17 accept-ranges: bytes etag: "3f30b1472d7d1c129b1273a8a4595b41" last-modified: Tue, 17 Oct 2023 14:39:21 GMT x-amz-request-id: b1350bc85b2e73b8

   time_namelookup:  0.002669s
   time_connect:  0.003485s
   time_appconnect:  0.009746s
   time_pretransfer:  0.009824s
   time_redirect:  0.000000s
   time_starttransfer:  0.052948s
                 ----------
   time_total:  0.053053s

bairamovazat avatar Oct 20 '23 10:10 bairamovazat

I also tested working through HttpClient. And based on wireshark everything works fine via http2.

HttpClient httpClient = HttpClient.newBuilder().version(HttpClient.Version.HTTP_2).build();
HttpRequest req = HttpRequest.newBuilder()
        .uri(new URI(publicFile))
        .GET().build();

HttpResponse<String> resp = httpClient.send(req,
        HttpResponse.BodyHandlers.ofString());

bairamovazat avatar Oct 27 '23 18:10 bairamovazat

The main difference is curl (or httpClient) and AWS SDK in alnp.

"Client Hello" from curl/httpClient:

image

"Client Hello" from aws sdk 2

image

I tried to add manually (in debug mode) alpn h2 In NettyUtils class. And I was able to execute 1 request. But then I got java.io.IOException: Read timed out.

 private static void configureSslEngine(SSLEngine sslEngine) {
    SSLParameters sslParameters = sslEngine.getSSLParameters();
    sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
    sslParameters.setApplicationProtocols(new String[]{"h2"});
    sslEngine.setSSLParameters(sslParameters);
    }

bairamovazat avatar Oct 27 '23 21:10 bairamovazat

I also have the same issue. When I try async client with HTTP/2 set, it fails with the described exception.

fatih-celonis avatar Dec 04 '23 15:12 fatih-celonis

I am also interest in updates about this issue regarding async clients with HTTP/2. Any updates on this?

KoljaKrueckmeyer avatar Feb 07 '24 16:02 KoljaKrueckmeyer

Hi @bairamovazat,

Apologies for the delayed response. I checked with the S3 team to confirm that S3 does not support HTTP/2 protocol.

Unsure whether you were previously able to connect directly to S3 with HTTP/2 protocol using the NettyNioAsyncHttpClient from Java SDK.

Regards, Chaitanya

bhoradc avatar Feb 08 '24 20:02 bhoradc

It looks like this issue has not been active for more than five days. In the absence of more information, we will be closing this issue soon. If you find that this is still a problem, please add a comment to prevent automatic closure, or if the issue is already closed please feel free to reopen it.

github-actions[bot] avatar Feb 18 '24 21:02 github-actions[bot]

Hey @bhoradc, do you mean that the SDK v2 client doesn't support H2?

mtheos avatar Apr 03 '24 23:04 mtheos