Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Presigned S3 with content-type="application/octet-stream" is always 403 #1233

Closed
polytropoi opened this issue Jan 7, 2019 · 6 comments
Closed
Assignees
Labels
AWS S3 Plugin that handles uploads to Amazon AWS S3

Comments

@polytropoi
Copy link

Using uppy with presigned s3 URLs works great for me as long as it's a recognized file type, but when the detected contentType is "application/octet-stream" it always fails with a 403, "The signature we calculated does not match..." error. Any help appreciated!

@goto-bus-stop
Copy link
Contributor

Hi! could you share a code sample that reproduces the problem? I tried uploading an extensionless file that was detected as application/octet-stream to our aws-presigned-url example, and it worked fine there.

@polytropoi
Copy link
Author

polytropoi commented Jan 15, 2019 via email

@polytropoi
Copy link
Author

polytropoi commented Jan 15, 2019 via email

@arturi arturi added the AWS S3 Plugin that handles uploads to Amazon AWS S3 label Jan 19, 2019
@trumpet2012
Copy link

I also ran into this error. For some reason Uppy does not add the Content-Type request header for files with a content-type of application/octet-stream. Since the signed url gets created with a content-type of application/octet-stream S3 is expecting the uploaded file be of the same content-type. Since the header is being excluded for these files and S3 does not require this header, S3 assumes the Content-Type header value is binary/octet-stream which doesn't match resulting in a 403 response.

To fix it I explicitly set the Content-Type header in the upload paramaters.

Here is the updated S3 configuration for the aws-presigned-example:

uppy.use(AwsS3, {
  getUploadParameters (file) {
    // Send a request to our PHP signing endpoint.
    return fetch('/s3-sign.php', {
      method: 'post',
      // Send and receive JSON.
      headers: {
        accept: 'application/json',
        'content-type': 'application/json'
      },
      body: JSON.stringify({
        filename: file.name,
        contentType: file.type
      })
    }).then((response) => {
      // Parse the JSON response.
      return response.json()
    }).then((data) => {
      // Return an object in the correct shape.
      return {
        method: data.method,
        url: data.url,
        fields: data.fields,
		// Always pass the Content-Type header to avoid issues with S3
        // assuming the wrong Content-Type
		headers: {
           "Content-Type": file.type
        }
      }
    })
  }
})

@goto-bus-stop
Copy link
Contributor

Finally getting to this 😅 right, Uppy doesn't set any content-type header, if it is there it's because the browser has decided on one. I don't know if we should set one ourselves, but we definitely should update the S3 examples with @trumpet2012's changes. It'd be good to keep doing that with presigned S3 uploads even if Uppy would set a content-type by default in the future, because you'll guarantee that the header and the signature used the same content type.

@scherroman
Copy link
Contributor

scherroman commented Feb 10, 2020

This was very confusing and frustrating for us, as the main S3 example in the documentation fails out of the box in many cases, and the generic S3 error message "the signature does not match" is not very helpful in diagnosing the root cause.

Some types of files like images upload successfully and other types like pdf and csv fail (because as we discovered through digging into the network tab in Chrome, a content type is attached for some file types but not others). +1 For uppy attaching a content type for S3 uploads by default, this would make the initial usage with S3 much easier. In the meantime, i've opened a pull request to update the docs here.

goto-bus-stop added a commit that referenced this issue Feb 12, 2020
* Add Content-Type header to presigned url example

Prevents the main presigned url example from failing in many cases, as the browser does not assign a content type in many cases, but a content type is required by S3. Based on issue #1233

* docs: code style

Co-authored-by: Renée Kooi <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
AWS S3 Plugin that handles uploads to Amazon AWS S3
Projects
None yet
Development

No branches or pull requests

5 participants