Search code examples
amazon-s3gcloudrails-activestorage

Google Cloud Storage CORS issue with Rails ActiveStorage


I've set the CORS for my bucket using gsutil with what I believe should work, but I haven't got past the "No 'Access-Control-Allow-Origin' header is present on the requested resource" error.

This is my cors json:

[
  {
    "origin": [
      "*"
    ],
    "responseHeader": [
      "Content-Type",
      "Content-MD5"
    ],
    "method": [
      "PUT",
      "POST",
      "GET",
      "HEAD",
      "DELETE",
      "OPTIONS"
    ],
    "maxAgeSeconds": 3600
  }
]

I've verified that this is actually being set:

gsutil cors get gs://mah-bucket
[{"maxAgeSeconds": 3600, "method": ["PUT", "POST", "GET", "HEAD", "DELETE", "OPTIONS"], "origin": ["*"], "responseHeader": ["Content-Type", "Content-MD5"]}]

These are the provisional headers on the failed request:

Content-MD5: Ug6Qj+DozqmniNxTXOYnDA==
Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document
Origin: https://subdomain.example.com
Referer: https://subdomain.example.com/
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36

I've already followed the advice here: https://github.com/rails/rails/issues/31523

I've tried a fresh incognito window as well so it's not caching anything from previous pre-flight requests.

Update: I've narrowed the problem down to an edge-case of ActiveStorage with the google service. Normal file upload forms work with both Amazon S3 and Google GCS services. Uploading using the ActiveStorage DirectUploadController js works with Amazon but not with Google.

The requests made in each case are identical save for a few auth differences between the services, but the responses to the pre-flight request are different. Here's the S3 pre-flight request response:

Access-Control-Allow-Headers: content-md5, content-type
Access-Control-Allow-Methods: PUT, POST, GET, HEAD
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 3600
Content-Length: 0
Date: Tue, 24 Jul 2018 22:32:51 GMT
Server: AmazonS3
Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method
x-amz-id-2: xxx/x/xxx
x-amz-request-id: xxx

Here's the GCS pre-flight request response:

access-control-allow-headers: Content-Type,Content-MD5
access-control-allow-methods: PUT,POST,GET,HEAD,DELETE,OPTIONS
access-control-allow-origin: *
access-control-max-age: 3600
alt-svc: quic=":443"; ma=2592000; v="44,43,39,35"
cache-control: private, max-age=0
content-length: 0
content-type: text/html; charset=UTF-8
date: Tue, 24 Jul 2018 22:43:25 GMT
expires: Tue, 24 Jul 2018 22:43:25 GMT
server: UploadServer
status: 200
x-guploader-uploadid: xxx-xxx

As stupid as it seems, this appears to be a case-sensitivity issue.


Solution

  • It turns out that the version of the direct_uploads_controller.js file I had copied out of Rails had a number of issues with browser and service compatibility. I copied over all the files in this folder and installed the missing spark-md5 package and all is well now: https://github.com/rails/rails/tree/master/activestorage/app/javascript/activestorage

    The commit I've tested is 372dda2a2950ad3ae5cf744ed8e3caa69a7ed44b.