Using CORS With Swift
What is CORS?
Cross-Origin Resource Sharing, or CORS, is a draft standard that enables web applications to make client-side requests to resources on another domain.
http://evil.example.com/ will not be able to load your bank’s web content and masquerade as a legitimate site. However, the same-origin security policy has the side effect of limiting some web application developers, too. The same-origin policy prevents a web application hosted at
http://app.example.com from uploading images directly to
http://images.example.com. CORS is the standard way to tell a browser that both sites are trusted and requests between the two should be allowed.
CORS and Swift
OpenStack Swift allows users to set CORS headers on data stored in Swift. This gives application developers the flexibility to upload data to Swift or host web content directly from Swift without having to build and maintain a separate proxying layer to get around the same-origin security model.
CORS headers in Swift are implemented on a per-container basis. To use CORS headers on data in your Swift cluster, set the appropriate metadata headers on your containers. Setting this container metadata causes all requests for objects in that container to return with the CORS headers and respond appropriately to
The headers you can set on your containers are:
X-Container-Meta-Access-Control-Allow-Origin X-Container-Meta-Access-Control-Max-Age X-Container-Meta-Access-Control-Allow-Headers X-Container-Meta-Access-Control-Expose-Headers
These are standard container metadata headers, but when a CORS request is made to the container or to an object in the container, these metadata entries are set on the response.
A Simple Demo
Let’s play with the CORS functionality in Swift.
First, let’s create a container with the CORS headers:
curl -i -XPUT -H "X-Auth-Token: exampletoken" \ -H "X-Container-Meta-Access-Control-Allow-Origin: http://webapp.example.com" \ http://swift.example.com/v1/AUTH_example/c
You can, of course, set headers on existing containers with a POST request.
Next let’s create an object in that container:
curl -i -XPUT --data-binary 1234 -H "X-Auth-Token: exampletoken" \ -H "X-Container-Meta-Access-Control-Allow-Origin: http://webapp.example.com" \ http://swift.example.com/v1/AUTH_example/c/o
And now we can make CORS requests and see what happens. The first request is the CORS pre-flight request. The draft spec defines a successful response as having a 200 status code and anything else as a CORS pre-flight request failure.
curl -i -XOPTIONS -H "X-Auth-Token: exampletoken" \ -H "Origin: http://webapp.example.com" \ -H "Access-Control-Request-Method: POST" \ http://swift.example.com/v1/AUTH_example/c/o HTTP/1.1 200 OK Access-Control-Allow-Origin: http://webapp.example.com Access-Control-Allow-Methods: HEAD, GET, PUT, POST, COPY, OPTIONS, DELETE Access-Control-Allow-Headers: x-auth-token Allow: HEAD, GET, PUT, POST, COPY, OPTIONS, DELETE Content-Length: 0 X-Trans-Id: txcfd8e244793046fcacbc7df4200e53c3 Date: Sat, 02 Feb 2013 07:35:23 GMT
Since we got a successful response, we can make the actual request:
curl -i -XPOST -H "X-Auth-Token: exampletoken" \ -H "Content-Type: text/plain" \ -H "Origin: http://webapp.example.com" \ http://swift.example.com/v1/AUTH_example/c/o HTTP/1.1 202 Accepted Access-Control-Allow-Origin: http://webapp.example.com Content-Type: text/html; charset=UTF-8 Content-Length: 76 Access-Control-Expose-Headers: cache-control, content-language, content-type, expires, last-modified, pragma, etag, x-timestamp, x-trans-id X-Trans-Id: txa73ddbc322e84484b542c9f1d39ed9d1 Date: Sat, 02 Feb 2013 07:38:07 GMT <html><h1>Accepted</h1><p>The request is accepted for processing.</p></html>