matsluni/aws-spi-akka-http

sdkclientexception "Unable to execute HTTP request: Service returned null 'Content-Length'."

Closed this issue · 7 comments

getting this

sdkclientexception "Unable to execute HTTP request: Service returned null 'Content-Length'."

@alexmnyc Thanks for forwarding the error message.
Can you provide more details, a reproducer or for which aws service this happens.
With the limited information you provided, I can't help you unfortunately.

I just received this as well when trying to download a file from an S3 bucket. Specifically

val getObjectFuture: CompletableFuture[ResponseBytes[GetObjectResponse]] = s3AsyncClient.getObject(
            getObjectRequest,
            new ByteArrayAsyncResponseTransformer[GetObjectResponse]()
            )
          FutureConverters.toScala(getObjectFuture)

I believe I may be experiencing a similar issue. Trying to stream an image file to S3, which the default client requires "Content-Length" to be set as it cannot be inferred. However, the response I get back from S3 has an error message The request signature we calculated does not match the signature you provided. Check your key and signing method. and the following entry for CanonicalRequest:

<CanonicalRequest>PUT
    REDACTED

    ...
    amz-sdk-retry:0/0/500
    content-disposition:inline
    content-length:
    content-type:image/jpeg
    host: REDACTED
    x-amz-content-sha256:UNSIGNED-PAYLOAD
    x-amz-date:20200610T002249Z

    amz-sdk-invocation-id;amz-sdk-retry;content-disposition;content-length;content-type;host;x-amz-content-sha256;x-amz-date
    UNSIGNED-PAYLOAD</CanonicalRequest>
vigoo commented

The PUT case seems to work if the Expect: 100-continue header is omitted from the request. I'm not sure though what exactly this mean (and an interesting fact that the same happens with a similar service provider I wrote for http4s)

Thanks @vigoo for linking the issues and proposing a possible fix.

IIVat commented

Today I have encountered with the issue as well. The problem is here:

RequestRunner.scala
val result = Http()
      .singleRequest(httpRequest, settings = connectionPoolSettings)
      .flatMap { response =>
        val sdkResponse = SdkHttpFullResponse.builder()
          .headers(response.headers.groupBy(_.name()).map{ case (k, v) => k -> v.map(_.value()).asJava }.asJava)
          .statusCode(response.status.intValue())
          .statusText(response.status.reason)
          .build

Headers are mapped from response, but cotent-length is not there. It is in HttpEntity. So solution is simple. To take cotent-length from HttpEntity and put it in headers.