Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate AWS S3 pre-signed URL request without knowing Content-Type?

I am generating in server side a pre-signed URL request with the following parameters for GeneratePresignedUrlRequest : bucket, key, expiration = in 1 hour and method = PUT.

In my Angular app, I am uploading the file using ng-file-upload

Upload.http({
    url: $scope.signedUrl,
    method: "PUT",
    headers : {
        'Content-Type': $scope.file.type
    },
    data: $scope.file
});

The problem is that I always have a 403 response unless I set the type of the file in GeneratePresignedUrlRequest.contentType.

The problem is that I can't predict in advance what type of file the user will choose (image/png, image/jpeg, text/plain...).

How can I generate a pre-signed url that accept all kinds of content-type ? I tried setting it to null, it keeps sending 403 errors.

Thanks.

like image 333
c4k Avatar asked Sep 07 '15 16:09

c4k


People also ask

How do I get pre-signed URL S3?

Sign in to the AWS Management Console and open the Amazon S3 console at https://console.aws.amazon.com/s3/ . In the Buckets list, choose the name of the bucket that contains the object that you want a presigned URL for. In the Objects list, select the object that you want to create a presigned URL for.

How do S3 pre-signed URLs work?

Pre-signed URLs are used to provide short-term access to a private object in your S3 bucket. They work by appending an AWS Access Key, expiration time, and Sigv4 signature as query parameters to the S3 object. There are two common use cases when you may want to use them: Simple, occasional sharing of private files.

What is difference between Presigned and signed URL?

Pre-signed Url used for creator, mean to upload new objects. Signed Url all about accessing existing objects.

What is pre-signed URL in AWS S3?

A pre-signed URL allows you to grant temporary access to users who don't have permission to directly run AWS operations in your account. A pre-signed URL is signed with your credentials and can be used by any user.


1 Answers

I just ran into this problem, and just got it working. Replace your Upload.http code with the following:

var reader = new FileReader();
var xhr = new XMLHttpRequest();

xhr.open("PUT", $scope.signedUrl);
reader.onload = function(evt) {
  xhr.send(evt.target.result);
};
reader.readAsArrayBuffer($scope.file);

The problem ends up being that S3 is looking for a specific Content-Type (binary/octet-stream), which it infers when you omit the Content-Type header.

like image 188
Luke L Avatar answered Oct 24 '22 01:10

Luke L