Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uploading file to S3 (proxied) http: ContentLength=... with Body length 0 #225

Open
adri opened this issue Aug 6, 2024 · 4 comments
Open

Comments

@adri
Copy link

adri commented Aug 6, 2024

Our goal is to use this library in a container to proxy file upload requests to S3. When doing so, we run into an error http: ContentLength=... with Body length 0. Any tips on how to resolve this?

Steps to reproduce

  1. Start image

    docker run --rm -ti \
       -v ~/.aws:/root/.aws \
       -p 8080:8080 \
       -e 'AWS_SDK_LOAD_CONFIG=true' \
       -e 'AWS_PROFILE=...' \
       public.ecr.aws/aws-observability/aws-sigv4-proxy:1.9 
    
  2. Send image

    curl 'http://127.0.0.1:8080/some-bucket/some-image.jpeg' --request PUT -H 'host: s3.us-west-1.amazonaws.com' -H 'Content-Type: image/jpeg' -d '@some-image.jpeg' -v
    

    Responds with

    http: ContentLength=6396 with Body length 0
    
  3. View debug logs

    DEBU[0279] Initial request dump:                         request="PUT /some-bucket/some-image.jpeg HTTP/1.1\r\nHost: s3.us-west-1.amazonaws.com\r\nAccept: */*\r\nContent-Length: 6396\r\nContent-Type: image/jpeg\r\nUser-Agent: curl/8.7.1\r\n\r\n\xff\xd8\xff\xe0\x10JFIF\x01\x01\x01\x01\xff\xfe>CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), default quality\xff\xdbC\b\x06\x06\a\x06\x05\b\a\a\a\t\t\b\f\x14\f\v\v\f\x19\x12\x13\x0f\x14\x1d\x1a\x1f\x1e\x1d\x1a\x1c\x1c $.' \",#\x1c\x1c(7),01444\x1f'9=82<.342\xff\xdbC\x01\t\t\t\f\v\f\x18\x1...."
    INFO[0279] DEBUG: Request Signature:
    ---[ CANONICAL STRING  ]-----------------------------
    PUT
    /some-bucket/some-image.jpeg
    X-Amz-Algorithm=.....3D&X-Amz-SignedHeaders=host
    host:s3.us-west-1.amazonaws.com
    
    host
    UNSIGNED-PAYLOAD
    ---[ STRING TO SIGN ]--------------------------------
    AWS4-HMAC-SHA256
    20240806T150733Z
    20240806/us-west-1/s3/aws4_request
    680fc63663aeeda666951559c7e4a2a80ac1a603ecd4507ef11d94ae626f65a3
    ---[ SIGNED URL ]------------------------------------
    https://s3.us-west-1.amazonaws.com/some-bucket/some-image.jpeg?X-Amz-Algorithm=.....3D&X-Amz-SignedHeaders=host&X-Amz-Signature=0f3783db1114899233f73bfe158f2ae959fe9cb52b2073cd8ecaeea0cdb55fac
    -----------------------------------------------------
    DEBU[0279] signed request                                region=us-west-1 service=s3
    DEBU[0279] Stripping Header:                             StripHeader=Authorization
    DEBU[0279] proxying request                              request="PUT /some-bucket/some-image.jpeg?X-Amz-Algorithm=.....3D&X-Amz-SignedHeaders=host&X-Amz-Signature=0f3783db1114899233f73bfe158f2ae959fe9cb52b2073cd8ecaeea0cdb55fac HTTP/1.1\r\nHost: s3.us-west-1.amazonaws.com\r\nTransfer-Encoding: identity\r\nAccept: */*\r\nContent-Length: 6396\r\nContent-Type: image/jpeg\r\nUser-Agent: curl/8.7.1\r\n\r\n"
    ERRO[0279] unable to proxy request                       error="Put \"https://s3.us-west-1.amazonaws.com/some-bucket/some-image.jpeg?X-Amz-Algorithm=.....3D&X-Amz-SignedHeaders=host&X-Amz-Signature=0f3783db1114899233f73bfe158f2ae959fe9cb52b2073cd8ecaeea0cdb55fac\": http: ContentLength=6396 with Body length 0"
    
@janavenkat
Copy link

cc @rapphil it would be great, if we get some help here.

@janavenkat
Copy link

@rapphil We tried to understand the problem.

What We Did

  1. Checked Body Reading:
    We ensured that the request body was read and reset correctly using readDownStreamRequestBody.

  2. Verified Header Handling:
    We made sure that Content-Length was set correctly based on the actual body length and that Transfer-Encoding was handled properly.

  3. Reviewed Signing Process:

    We examined the sign method to ensure it didn’t alter the request body or headers in a way that could cause the mismatch.

  4. Verified Request Handling:

    We looked into how the ProxyClient was creating and sending requests to ensure consistent body and header handling.
    Conclusion

Issue: The mismatch between Content-Length and the actual body length remains unresolved.

@janavenkat
Copy link

cc @alvinlin123

ruudk added a commit to ruudk/aws-sigv4-proxy that referenced this issue Nov 8, 2024
Fixes awslabs#225

The problem is the the `sign` method in ProxyClient reads the `req.Body` and that results
in a closed reader.

When the request is actually send to the transport later, the body cannot be read and results
in a body length of 0 which does not match the passed req.ContentLength.

We tried to write tests for this, but the tests are not fully matching the real world because:
* they use io.NopCloser
* they use a HTTP mock client that doesn't actually read the body to send to the proxy (makes sense,
its a mock, but it's different than the actual implementation)
@ruudk
Copy link

ruudk commented Nov 8, 2024

We fixed the problem in #229

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants