Question:
I’m uploading a mp4
video to AWS S3 using a pre-signed URL, the upload succeeds but when I try to download the video from S3 and play it in a media player (VLC or quickTime), it doesn’t play!.
Generated pre-signed URL works fine with mp3
but the same problem as above also occurs for WAV
and FLAC
.
Code to generate the pre-signed url:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public String getPreSignedS3Url( final String userId, final String fileName ) { Date expiration = new Date(); long expTimeMillis = expiration.getTime(); expTimeMillis += urlExpiry; expiration.setTime(expTimeMillis); String objectKey = StringUtils.getObjectKey( userId, fileName ); GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest( recordingBucketName, objectKey) .withMethod(HttpMethod.PUT) .withExpiration(expiration); URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest); return url.toString(); } |
After I get the pre-signed URL from the method above, I make a HTTP PUT request from Postman with the multipart/form-data in the request body like this:
1 2 3 4 |
-H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \ -F 'file=@/Users/john/Downloads/sampleDemo.mp4' |
pre-signed url looks like this:
1 2 |
https://meeting-recording.s3.eu-west-2.amazonaws.com/331902257/sampleDemo.mp4?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20190720T125751Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3599&X-Amz-Credential=AKIAZDSMLZ3VDKNXQUXH%2F20190720%2Feu-west-2%2Fs3%2Faws4_request&X-Amz-Signature=dfb8054f0738e07e925e9880e4a8e5ebba0a1bd3c84a3ec78913239f65221992 |
I tried to set the content type to mp4 in the getPreSignedS3Url()
method using generatePresignedUrlRequest.setContentType( "video/mp4" );
and add Content-Type : "video/mp4"
in the HTTP PUT request header but it didn’t work and it fails with an error Signature doesn't match
.
I’m using S3 as my personal back-up hard-drive, I expect to upload video and audio files to S3 using a pre-signed URL, download them at some point in the future and be able to play them, but I’m unable to play them after I have downloaded them.
Does anyone know what could be causing this?
Answer:
PUT
requests to S3 don’t support multipart/form-data
. The request body needs to contain nothing but the binary object data. If you download your existing file from S3 and open it with a text editor, you’ll find that S3 has preserved the multipart form structure inside the file, instead of interpreting it as a wrapper for the actual payload.