13.3. CORS

Cross-Origin Resource Sharing (CORS) is a mechanism that allows code running in a browser to make requests to a domain other than the one from which it originated. CORS container headers enable your users to upload files from one website, or origin, to your Cloud Files account. When you set the CORS headers on your container, you provide Cloud Files with the following information:

  • Which sites can post to your account

  • How often your container checks its allowed sites list

  • What headers to expose to the browser in the request response


You use CORS with the following features:

Cloud Files supports CORS requests to containers and objects. CORS metadata is held on the container only. The values given apply to the container itself and all objects within it.

The following table lists the supported container headers.

Table 13.1. Supported CORS container headers
X-Container-Meta-Access-Control-Allow-Origin Origins that are allowed to make cross-origin requests, separated by a space when there are multiple values.
X-Container-Meta-Access-Control-Max-Age Maximum age for the origin to hold the preflight results, in seconds (for example, 5, 10, or 1000).
X-Container-Meta-Access-Control-Expose-Headers Headers exposed to the browser in the actual request response, separated by a space when there are multiple values.

Before a browser issues an actual request, it might issue a preflight request. The preflight request is an HTTP OPTIONS call to verify that the origin is allowed to make the request. Following is the sequence of actions:

  1. The browser makes an OPTIONS request to Cloud Files.

  2. Cloud Files returns either a 200 or 401 status code to the browser based on the allowed origins.

  3. If Cloud Files returns 200, the browser makes the actual request (DELETE, GET, HEAD, POST, PUT) to Cloud Files.

When a browser receives a response to an actual request, it exposes only those headers listed in the X-Container-Meta-Access-Control-Expose-Headers header. By default, Cloud Files returns the following values for this header:

  • The simple response headers as listed at www.w3.org/TR/cors/#simple-response-header/

  • The ETag, X-Timestamp, and X-Trans-Id headers

  • All metadata headers (X-Container-Meta-name for containers and X-Object-Meta-name for objects)

  • Headers listed in X-Container-Meta-Access-Control-Expose-Headers

To see some CORS JavaScript in action, follow these steps:

  1. Download the Example 13.11, “Test CORS page”.

  2. Host the page on a web server and note the protocol and hostname (origin) you will be using to request the page, for example http://localhost.

  3. Locate a container that you want to query. (The Cloud Files cluster hosting this container must have CORS support.)

  4. Append the origin of the test page to the container’s X-Container-Meta-Access-Control-Allow-Origin header, using a request similar to the following example.


Example 13.10. CORS POST cURL request

curl -X POST -H 'X-Auth-Token: f064c46a782c444cb4ba4b6434288f7c' \
  -H 'X-Container-Meta-Access-Control-Allow-Origin: http://localhost' \

At this point, the container is accessible to CORS clients hosted on http://localhost. Open the test CORS page in your browser and following these steps:

  1. Populate the Token field.

  2. Populate the URL field with the URL of either a container or object.

  3. Select the request method.

  4. Hit Submit.

If the request succeeds, the response header and body are displayed. If the request did not succeed, the response status is 0.


Example 13.11. Test CORS page

<!DOCTYPE html>
    <meta charset="utf-8">
    <title>Test CORS</title>

    Token<br><input id="token" type="text" size="64"><br><br>

    <select id="method">
        <option value="GET">GET</option>
        <option value="HEAD">HEAD</option>
        <option value="POST">POST</option>
        <option value="DELETE">DELETE</option>
        <option value="PUT">PUT</option>

    URL (Container or Object)<br><input id="url" size="64" type="text"><br><br>

    <input id="submit" type="button" value="Submit" onclick="submit(); return false;">

    <pre id="response_headers"></pre>
    <pre id="response_body"></pre>

    <script type="text/javascript">
      function submit() {
          var token = document.getElementById('token').value;
          var method = document.getElementById('method').value;
          var url = document.getElementById('url').value;

          document.getElementById('response_headers').textContent = null;
          document.getElementById('response_body').textContent = null;

          var request = new XMLHttpRequest();

          request.onreadystatechange = function (oEvent) {
              if (request.readyState == 4) {
                  responseHeaders = 'Status: ' + request.status;
                  responseHeaders = responseHeaders + '\nStatus Text: ' + request.statusText;
                  responseHeaders = responseHeaders + '\n\n' + request.getAllResponseHeaders();
                  document.getElementById('response_headers').textContent = responseHeaders;
                  document.getElementById('response_body').textContent = request.responseText;

          request.open(method, url);
          request.setRequestHeader('X-Auth-Token', token);


loading table of contents...