1

I'm trying to upload an image from Android device's gallery to a S3 bucket using a pre-signed url that I get from an API which I've been given.

I'm getting a 403 - Forbidden error when trying to upload the image. Below is my code.

Retrofit interface:

// Upload image to s3
@PUT("{uploadUri}")
Call<ResponseBody> uploadImage(
        @Path("uploadUri") String uploadUri,
        @Body File file
);

Relevant code from activity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test);

    ... 
    Button uploadBtn = (Button)findViewById(R.id.uploadbtn);
    uploadBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent();
            intent.setType("image/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(
                    Intent.createChooser(intent, "Select Picture"),
                    PICK_IMAGE_FROM_GALLERY_REQUEST);
        }
    });
}

public void uploadFile(Uri fileUri){
    originalFile = FileUtils.getFile(this, fileUri);
    File file = new File(originalFile.getPath());

    //Create retrofit instance
    Retrofit.Builder builder = new Retrofit.Builder()
            .baseUrl(baseURL)
            .addConverterFactory(GsonConverterFactory.create());
    Retrofit retrofit = builder.build();
    ApiInterface client = retrofit.create(ApiInterface.class);

    Call<ResponseBody> call = client.uploadImage(uploadUri, file);
    call.enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
            int statusCode = response.code();
            if(statusCode == 200){
                Toast.makeText(TestActivity.this, "Success!", Toast.LENGTH_SHORT).show();
            }
            else{
                Toast.makeText(TestActivity.this, "Failure " + statusCode, Toast.LENGTH_SHORT).show();
                Log.d("Failure: ", response.message());
                Log.d("Failure: ", response.headers().toString());
            }
        }
        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            Toast.makeText(TestActivity.this, "Failure", Toast.LENGTH_SHORT).show();
            Log.d("Failure: ", t.getMessage());
            t.printStackTrace();
        }
    });
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if(requestCode == PICK_IMAGE_FROM_GALLERY_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null){
        Uri uri = data.getData();
        Log.d("uri: ", uri.toString());
        ContentResolver cr = getContentResolver();
        String mimetype = cr.getType(uri);
        Log.d("mimetype: ", mimetype);
        uploadFile(uri);
    }
}

What I'm getting from logcat:

09-26 11:00:07.869 3295-3295/com.example.erawi D/SignedRequest::
https://test-name.s3.amazonaws.com/59ca33381cd9961425046d3c5b?AWSAccessKeyId=AKIAIAOASKDVRB2VL7LQ&Content-Type=image%2Fpng&Expires=1506423668&Signature=8JKskq%2BZLiYItas8k4%2FoQpRgKhk%3D&x-amz-acl=public-read
09-26 11:00:07.869 3295-3295/com.example.erawi D/URL:: https://test-name.s3.amazonaws.com/59ca33381cd9961425046d3c5b
09-26 11:00:17.394 3295-3295/com.example.erawi D/uri:: content://com.android.providers.media.documents/document/image%3A102
09-26 11:00:17.415 3295-3295/com.example.erawi D/mimetype:: image/png
09-26 11:00:18.088 3295-3295/com.example.erawi D/Failure:: Forbidden
09-26 11:00:18.088 3295-3295/com.example.erawi D/Failure:: x-amz-request-id: D444F94AS5C3BAF2
x-amz-id-2: MM6KkMJ1PSvDVo86A4123Sf0InM0S/FUP1czIxpvaOdRJnhcgWqwQeu3bkS4puTDlrBpZS6JX/s=
Content-Type: application/xml
Transfer-Encoding: chunked
Date: Tue, 26 Sep 2017 11:00:17 GMT
Connection: close
Server: AmazonS3

File uploading is working with javascript in browser but not in android.

Config for bucket:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
   <AllowedOrigin>*</AllowedOrigin>
   <AllowedMethod>GET</AllowedMethod>
   <AllowedMethod>POST</AllowedMethod>
   <AllowedMethod>PUT</AllowedMethod>
   <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
Michael - sqlbot
  • 169,571
  • 25
  • 353
  • 427
EraWi
  • 37
  • 6
  • You are not sending token or any auth info. `403` -> unauthorized/unauthenticated – Cătălin Florescu Sep 27 '17 at 07:10
  • 1
    @FlorescuGeorgeCătălin It must be something related to Content-Type or signedURI.... it doesnt have to do with unauthentication, as 403 usually means. – Prata Sep 28 '17 at 08:38

0 Answers0