swift/doc/source/cors.rst
Chmouel Boudjnah c687f6956c Allow all headers requested for CORS.
- We allow all headers requested in preflight request. The CORS
  specification does leave the door open for this, as mentioned in
  http://www.w3.org/TR/cors/#resource-preflight-requests
  Note: Since the list of headers can be unbounded
  simply returning headers can be enough.
- This is a followup to review:
  https://review.openstack.org/#/c/24415/.
- Fixes bug 1155034.

Change-Id: If7b8f2f3a581c5209892d1ccc9f06ddb8fac92dd
2013-04-05 21:12:15 +01:00

148 lines
5.8 KiB
ReStructuredText

====
CORS
====
CORS_ is a mechanisim to allow code running in a browser (Javascript for
example) make requests to a domain other then the one from where it originated.
Swift 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 supported headers are,
+---------------------------------------------+-------------------------------+
|Metadata | Use |
+==============================================+==============================+
|X-Container-Meta-Access-Control-Allow-Origin | Origins to be allowed to |
| | make Cross Origin Requests, |
| | space separated. |
+----------------------------------------------+------------------------------+
|X-Container-Meta-Access-Control-Max-Age | Max age for the Origin to |
| | hold the preflight results. |
+----------------------------------------------+------------------------------+
|X-Container-Meta-Access-Control-Expose-Headers| Headers exposed to the user |
| | agent (e.g. browser) in the |
| | the actual request response. |
| | Space separated. |
+----------------------------------------------+------------------------------+
Before a browser issues an actual request it may issue a `preflight request`_.
The preflight request is an OPTIONS call to verify the Origin is allowed to
make the request. The sequence of events are,
* Browser makes OPTIONS request to Swift
* Swift returns 200/401 to browser based on allowed origins
* If 200, browser makes the "actual request" to Swift, i.e. PUT, POST, DELETE,
HEAD, GET
When a browser receives a response to an actual request it only exposes those
headers listed in the ``Access-Control-Expose-Headers`` header. By default Swift
returns the following values for this header,
* "simple response headers" as listed on
http://www.w3.org/TR/cors/#simple-response-header
* the headers ``etag``, ``x-timestamp``, ``x-trans-id``
* all metadata headers (``X-Container-Meta-*`` for containers and
``X-Object-Meta-*`` for objects)
* headers listed in ``X-Container-Meta-Access-Control-Expose-Headers``
-----------------
Sample Javascript
-----------------
To see some CORS Javascript in action download the `test CORS page`_ (source
below). Host it on a webserver and take note of the protocol and hostname
(origin) you'll be using to request the page, e.g. http://localhost.
Locate a container you'd like to query. Needless to say the Swift cluster
hosting this container should have CORS support. Append the origin of the
test page to the container's ``X-Container-Meta-Access-Control-Allow-Origin``
header,::
curl -X POST -H 'X-Auth-Token: xxx' \
-H 'X-Container-Meta-Access-Control-Allow-Origin: http://localhost' \
http://192.168.56.3:8080/v1/AUTH_test/cont1
At this point the container is now accessible to CORS clients hosted on
http://localhost. Open the test CORS page in your browser.
#. Populate the Token field
#. Populate the URL field with the URL of either a container or object
#. Select the request method
#. Hit Submit
Assuming the request succeeds you should see the response header and body. If
something went wrong the response status will be 0.
.. _test CORS page:
Test CORS Page
--------------
::
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test CORS</title>
</head>
<body>
Token<br><input id="token" type="text" size="64"><br><br>
Method<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>
</select><br><br>
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>
<p>
<hr>
<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);
request.send(null);
}
</script>
</body>
</html>
.. _CORS: https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS
.. _preflight request: https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS#Preflighted_requests