2

I am getting the presigned URL from Lambda, but not sure why when I make a PUT request to that generated URL, my image is not being uploaded to S3.

I've followed these two answers exactly, but it's still not working for me

https://stackoverflow.com/a/46177449/11110509

https://stackoverflow.com/a/46579224/11110509

Could someone point out what I'm doing wrong?

public interface IUploadImages{
   @PUT
   Call<String> listRepos(@Url String url, @Body RequestBody image);
}

And my call to upload the image:

        //Already checked to make sure mImageUri is not null
        File file = new File(StringUtils.getPath(this, mImageUri));
        RequestBody requestFile = RequestBody.create(MediaType.parse("image/jpeg"), file);

        RetrofitInterfaces.IUploadImages service = RetrofitClientInstance.getRetrofitInstance()
                .create(RetrofitInterfaces.IUploadImages.class);
        //Also checked to make sure mGeneraredUrl is also not null
        Call<String> call = service.listRepos(mGeneratedUrl, requestFile);
        call.enqueue(new Callback<String>() {
            @Override
            public void onResponse(Call<String> call, Response<String> response) {
                if(response.isSuccessful()){
                    Log.d(TAG, "onResponse: Success?");
                }
            }

            @Override
            public void onFailure(Call<String> call, Throwable t) {
                Log.d(TAG, "onFailure: Failed: " + t);
            }
        });         

I've made the bucket public. The call is not failing, but in onResponse I'm getting a response code of 403.

DIRTY DAVE
  • 2,523
  • 2
  • 20
  • 83

1 Answers1

3

Finally figured it out.. your presigned url function needs to have the same content type as

RequestBody.create(MediaType.parse("image/jpeg"), file);

So in my params

var params = {
    Bucket: 'my-bucket-name',
    Key: 'test-key',
    Expires: signedUrlExpireSeconds,
    ContentType: "image/jpeg"
};

Content type needs to be the same client side and in function side otherwise you get a 403 error...

DIRTY DAVE
  • 2,523
  • 2
  • 20
  • 83
  • 1
    This is related to why `params` needs `ContentType` to be provided in the first place -- it's a header whose value must be included in the inputs to the signing algorithm any time it is present in the request that is being sent to S3. – Michael - sqlbot Jan 11 '20 at 02:16