amazonka icon indicating copy to clipboard operation
amazonka copied to clipboard

Can't add "Content-Length" header to presigned PUT URL

Open adlaika opened this issue 2 years ago • 4 comments

I'm trying to enforce file size limits on presigned PUTs as per the top answer on this post: https://stackoverflow.com/questions/25991275/limit-size-of-objects-while-uploading-to-amazon-s3-using-pre-signed-url

However, the following code results in a presigned URL that does not contain the signed header "Content-Length":

import ClassyPrelude
import Amazonka.Presign (presignWithHeaders, defaultHeaders)
import Network.URI ( uriToString )

presignWithContentLength auth envOverride' = do
  let headers = defaultHeaders . (<> [("Content-Length", "10000000")]
  presignedRequest <- presignWithHeaders headers envOverride' auth (region config) now 120 (newPutObject (BucketName bucketName) (ObjectKey objKey) (toBody ("" :: ByteString)))
  let result = (uriToString id $ getUri presignedRequest) ""
  pure $ toText result

Am I doing something wrong?

adlaika avatar Aug 08 '22 20:08 adlaika

For next time, please upload a minimal reproduction that compiles. I had to wrangle a fair bit by hand to get everything set up.

It looks like the Content-Length header is explicitly deleted when headers are normalised:

https://github.com/brendanhay/amazonka/blob/098795f847df7239af64535c6b2b233f3fbd699c/lib/amazonka-core/src/Amazonka/Sign/V4/Base.hs#L290

This appears to have initially been done in a3eabd987287bd5117faa07cb2875bad2ed9ae21 because you're not allowed to send content-length when using SigV4 streaming signatures (to S3).

I don't plan to fix this anytime soon. Updating to latest botocore and generating new service bindings are higher priority, but if you'd like to try I think the trick will be to parameterise signMetadata in Amazonka.Sign.V4.Base so that we can differentiate between signing metadata for a chunked body, for a hashed body, or for a presign. A three-valued enum data SigningType = Presign | HashedBody | ChunkedBody is probably the way to go.

endgame avatar Aug 11 '22 12:08 endgame

Ah, sorry about that.

Thanks for the info--I'll look into your solution.

adlaika avatar Aug 16 '22 19:08 adlaika

I will have bandwidth to look at and merge a PR, so let me know if you do give this a go.

endgame avatar Aug 16 '22 21:08 endgame

If I'm able to, it won't be for several weeks at minimum. Startup life :)

adlaika avatar Aug 16 '22 21:08 adlaika