CORS issue when uploading file using presigned POST URL
Hi! I'm migrating some of our tests from Localstack to S3Mock (great work, btw!), but I've encountered an issue where one of our tests fails when uploading a file to S3Mock using a presigned POST URL.
The request includes the Access-Control-Allow-Methods: POST header, and this seems to cause the failure. I've tried reproducing the issue, and you can see the failing test case here: https://github.com/fabiob/S3Mock/commit/c7679fc8d8c84e3c7378f49f2d69741a6c71f7eb
What I've tried:
- Allowing POST in controller annotations: Added
@CrossOrigin(..., methods = {Request.POST, ...})to the controllers: https://github.com/fabiob/S3Mock/commit/79057ce74010360a59ae787a82df2b34569b5668 - Configuring CORS globally: Removed the
@CrossOriginannotations from the controllers and tried configuring CORS globally by overridingS3MockConfiguration.addCorsMappings: https://github.com/fabiob/S3Mock/commit/0c6d2c4a3e917368ffa35210d777769ae07032cb - Using CORS filter: Removed the
@CrossOriginannotations and added a CORS filter usingFilterRegistrationBeantoS3MockConfiguration: https://github.com/fabiob/S3Mock/commit/ebe7d5e363dec5a6fb469c315c883744a00a348d
None of these attempts seem to resolve the issue. The test still fails when performing the OPTIONS request.
Any insights or workarounds from others who may have experienced this issue would be greatly appreciated!
References I've used:
- https://spring.io/blog/2015/06/08/cors-support-in-spring-framework#global-cors-configuration
@fabiob which URL are you trying to POST to?
The controllers are annotated with @CrossOrigin(origins = "*", exposedHeaders = "*") which means that the HTTP methods allowed default to the HTTP method declared by the controller function.
There are only a few S3 APIs that allow POST requests, most APIs use PUT to modify or create data.
The only APIs supported by S3Mock using POST are deleteObjects, createMultipartUpload and completeMultipartUpload.
The reason why your test fails is because the URL used points to a bucket (https://github.com/fabiob/S3Mock/commit/c7679fc8d8c84e3c7378f49f2d69741a6c71f7eb#diff-830d0afe6486c2b436b422fabcb308511dab2b2eef4c1edf698108716a4d7b0dR228), and there are no APIs that allow a POST on a bucket.
if you change your test to use "PUT" instead, it succeeds, as there are two APIs (and controller functions) that allow a "PUT" on a bucket, for example putObjectLockConfiguration
You write "upload file" - do you mean "putObject"? This API needs a "PUT", not a "POST" request: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html
I'm running into this as well. I'm using boto's generate_presigned_post method, which specifically returns a URL to post to. For context, in a local env, I'm trying to get a presigned post URL from the S3Mock container and then post to it.
@afranken Do you have any context on this by chance? Should POST be supported for presigned URLs?
@jedkass didn't have time yet to look into this. As I said in an earlier comment, the S3 API supports POST requests only for a few resources, everywhere else, PUT is used. You can't just generate a presigned URL allowing POST and then make the POST request for an API that disallows that HTTP verb...
It would be good to have specific test cases that work against S3 directly and fail against S3Mock for APIs that allow POST.
Just merged tests for GET, HEAD, DELETE and POST options requests. Success depends on the APIs being called.
As I wrote in previous comments, creating presigned URLs may work locally using the AWS SDK for arbitrary URLs, but the S3 API (and S3Mock) will refuse connection if the API called does not allow for the HTTP method used.
Please refer to the S3 API to learn about the HTTP methods used for API calls: https://docs.aws.amazon.com/AmazonS3/latest/API/Welcome.html
@afranken Do you have any context on this by chance? Should
POSTbe supported for presigned URLs?
@jedkass good news: I released https://github.com/adobe/S3Mock/releases/tag/4.1.0 S3Mock now supports POST Object requests (with basic parameters).
See also #2200