Merge "Adds v1 API documentation to doc/source/api"

This commit is contained in:
Jenkins 2014-11-19 23:39:06 +00:00 committed by Gerrit Code Review
commit a590e84a53
11 changed files with 1240 additions and 1 deletions

View File

@ -0,0 +1,54 @@
==============
Authentication
==============
The owner of an Object Storage account controls access to that account
and its containers and objects. An owner is the user who has the
''admin'' role for that tenant. The tenant is also known as the project
or account. As the account owner, you can modify account metadata and
create, modify, and delete containers and objects.
To identify yourself as the account owner, include an authentication
token in the ''X-Auth-Token'' header in the API request.
Depending on the token value in the ''X-Auth-Token'' header, one of the
following actions occur:
- ''X-Auth-Token'' contains the token for the account owner.
The request is permitted and has full access to make changes to the
account.
- The ''X-Auth-Token'' header is omitted or it contains a token for a
non-owner or a token that is not valid.
The request fails with a 401 Unauthorized or 403 Forbidden response.
You have no access to accounts or containers, unless an access
control list (ACL) explicitly grants access.
The account owner can grant account and container access to users
through access control lists (ACLs).
The following list describes the authentication services that you can
use with Object Storage:
- OpenStack Identity (keystone): For Object Storage, account is synonymous with
project or tenant ID.
- Tempauth middleware: Object Storage includes this middleware. User and account
management is performed in Object Storage itself.
- Swauth middleware: Stored in github, this custom middleware is modeled on
Tempauth. Usage is similar to Tempauth.
- Other custom middleware: Write it yourself to fit your environment.
Specifically, you use the ''X-Auth-Token'' header to pass an
authentication token to an API request.
Authentication tokens expire after a time period that the authentication
service defines. When a token expires, use of the token causes requests
to fail with a 401 Unauthorized response. To continue, you must obtain a
new token.

View File

@ -0,0 +1,30 @@
================
Container quotas
================
You can set quotas on the size and number of objects stored in a
container by setting the following metadata:
- ``X-Container-Meta-Quota-Bytes``. The size, in bytes, of objects that
can be stored in a container.
- ``X-Container-Meta-Quota-Count``. The number of objects that can be
stored in a container.
When you exceed a container quota, subsequent requests to create objects
fail with a 413 Request Entity Too Large error.
The Object Storage system uses an eventual consistency model. When you
create a new object, the container size and object count might not be
immediately updated. Consequently, you might be allowed to create
objects even though you have actually exceeded the quota.
At some later time, the system updates the container size and object
count to the actual values. At this time, subsequent requests fails. In
addition, if you are currently under the
``X-Container-Meta-Quota-Bytes`` limit and a request uses chunked
transfer encoding, the system cannot know if the request will exceed the
quota so the system allows the request. However, once the quota is
exceeded, any subsequent uploads that use chunked transfer encoding
fail.

View File

@ -0,0 +1,37 @@
===============
Discoverability
===============
Your Object Storage system might not enable all features that you read about because your service provider chooses which features to enable.
To discover which features are enabled in your Object Storage system,
use the ``/info`` request. However, your service provider might have
disabled the ``/info`` request, or you might be using an older version
that does not support the ``/info`` request.
To use the ``/info`` request, send a **GET** request using the ``/info``
path to the Object Store endpoint as shown in this example:
.. code::
# curl https://storage.clouddrive.com/info
This example shows a truncated response body:
.. code::
{
"swift":{
"version":"1.11.0"
},
"staticweb":{
},
"tempurl":{
}
}
This output shows that the Object Storage system has enabled the static
website and temporary URL features.

View File

@ -0,0 +1,214 @@
====================
Form POST middleware
====================
To discover whether your Object Storage system supports this feature,
check with your service provider or send a **GET** request using the ``/info``
path.
You can upload objects directly to the Object Storage system from a
browser by using the form **POST** middleware. This middleware uses
account secret keys to generate a cryptographic signature for the
request. This means that you do not need to send an authentication token
in the ``X-Auth-Token`` header to perform the request.
The form **POST** middleware uses the same secret keys as the temporary
URL middleware uses. For information about how to set these keys, see account secret keys.
For information about the form **POST** middleware configuration
options, see `Form
post <http://docs.openstack.org/havana/config-reference/content/object-storage-form-post.html>`__
in the *OpenStack Configuration Reference*.
Form POST format
~~~~~~~~~~~~~~~~
To upload objects to a cluster, you can use an HTML form **POST**
request.
The format of the form **POST** request is:
**Example 1.14. Form POST format**
.. code::
&lt;![CDATA[
<form action="SWIFT_URL"
method="POST"
enctype="multipart/form-data">
<input type="hidden" name="redirect" value="REDIRECT_URL"/>
<input type="hidden" name="max_file_size" value="BYTES"/>
<input type="hidden" name="max_file_count" value="COUNT"/>
<input type="hidden" name="expires" value="UNIX_TIMESTAMP"/>
<input type="hidden" name="signature" value="HMAC"/>
<input type="file" name="FILE_NAME"/>
<br/>
<input type="submit"/>
</form>
]]&gt;
**``action="SWIFT_URL``"**
Set to full URL where the objects are to be uploaded. The names of
uploaded files are appended to the specified *``SWIFT_URL``*. So, you
can upload directly to the root of a container with a URL like:
.. code::
https://swift-cluster.example.com/v1/my_account/container/
Optionally, you can include an object prefix to separate uploads, such
as:
.. code::
https://swift-cluster.example.com/v1/my_account/container/OBJECT_PREFIX
**method="POST"**
Must be ``POST``.
**enctype="multipart/form-data"**
Must be ``multipart/form-data``.
**name="redirect" value="*``REDIRECT_URL``*\ "**
Redirects the browser to the *``REDIRECT_URL``* after the upload
completes. The URL has status and message query parameters added to it,
which specify the HTTP status code for the upload and an optional error
message. The 2\ *``nn``* status code indicates success.
The *``REDIRECT_URL``* can be an empty string. If so, the ``Location``
response header is not set.
**name="max\_file\_size" value="*``BYTES``*\ "**
Required. Indicates the size, in bytes, of the maximum single file
upload.
**name="max\_file\_count" value= "*``COUNT``*\ "**
Required. Indicates the maximum number of files that can be uploaded
with the form.
**name="expires" value="*``UNIX_TIMESTAMP``*\ "**
The UNIX timestamp that specifies the time before which the form must be
submitted before it becomes no longer valid.
**name="signature" value="*``HMAC``*\ "**
The HMAC-SHA1 signature of the form.
**type="file" name="*``FILE_NAME``*\ "**
File name of the file to be uploaded. You can include from one to the
``max_file_count`` value of files.
The file attributes must appear after the other attributes to be
processed correctly.
If attributes appear after the file attributes, they are not sent with
the sub-request because all attributes in the file cannot be parsed on
the server side unless the whole file is read into memory; the server
does not have enough memory to service these requests. Attributes that
follow the file attributes are ignored.
Optionally, if you want the uploaded files to be temporary you can set x-delete-at or x-delete-after attributes by adding one of these as a form input:
..code::
<input type="hidden" name="x_delete_at" value="<unix-timestamp>" />
<input type="hidden" name="x_delete_after" value="<seconds>" />
**type= "submit"**
Must be ``submit``.
HMAC-SHA1 signature for form POST
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Form **POST** middleware uses an HMAC-SHA1 cryptographic signature. This
signature includes these elements from the form:
- The path. Starting with ``/v1/`` onwards and including a container
name and, optionally, an object prefix. In `Example 1.15, “HMAC-SHA1
signature for form
POST” the path is
``/v1/my_account/container/object_prefix``. Do not URL-encode the
path at this stage.
- A redirect URL. If there is no redirect URL, use the empty string.
- Maximum file size. In `Example 1.15, “HMAC-SHA1 signature for form
POST” the
``max_file_size`` is ``104857600`` bytes.
- The maximum number of objects to upload. In `Example 1.15, “HMAC-SHA1
signature for form
POST” ``max_file_count`` is ``10``.
- Expiry time. In `Example 1.15, “HMAC-SHA1 signature for form
POST” the expiry time
is set to ``600`` seconds into the future.
- The secret key. Set as the ``X-Account-Meta-Temp-URL-Key`` header
value.
The following example code generates a signature for use with form
**POST**:
**Example 1.15. HMAC-SHA1 signature for form POST**
.. code::
import hmac
from hashlib import sha1
from time import time
path = '/v1/my_account/container/object_prefix'
redirect = 'https://myserver.com/some-page'
max_file_size = 104857600
max_file_count = 10
expires = int(time() + 600)
key = 'MYKEY'
hmac_body = '%s\n%s\n%s\n%s\n%s' % (path, redirect,
max_file_size, max_file_count, expires)
signature = hmac.new(key, hmac_body, sha1).hexdigest()
For more information, see `RFC 2104: HMAC: Keyed-Hashing for Message
Authentication <http://www.ietf.org/rfc/rfc2104.txt>`__.
Form POST example
~~~~~~~~~~~~~~~~~
The following example shows how to submit a form by using a cURL
command. In this example, the object prefix is ``photos/`` and the file
being uploaded is called ``flower.jpg``.
This example uses the **swift-form-signature** script to compute the
``expires`` and ``signature`` values.
.. code::
$ bin/swift-form-signature /v1/my_account/container/photos/ https://example.com/done.html 5373952000 1 200 MYKEY
Expires: 1390825338
Signature: 35129416ebda2f1a21b3c2b8939850dfc63d8f43
.. code::
$ curl -i https://swift-cluster.example.com/v1/my_account/container/photos/ -X POST \
-F max_file_size=5373952000 -F max_file_count=1 -F expires=1390825338 \
-F signature=35129416ebda2f1a21b3c2b8939850dfc63d8f43 \
-F redirect=https://example.com/done.html \
-F file=@flower.jpg

View File

@ -0,0 +1,295 @@
=============
Large objects
=============
By default, the content of an object cannot be greater than 5 GB.
However, you can use a number of smaller objects to construct a large
object. The large object is comprised of two types of objects:
- **Segment objects** store the object content. You can divide your
content into segments, and upload each segment into its own segment
object. Segment objects do not have any special features. You create,
update, download, and delete segment objects just as you would normal
objects.
- A **manifest object** links the segment objects into one logical
large object. When you download a manifest object, Object Storage
concatenates and returns the contents of the segment objects in the
response body of the request. This behavior extends to the response
headers returned by **GET** and **HEAD** requests. The
``Content-Length`` response header value is the total size of all
segment objects. Object Storage calculates the ``ETag`` response
header value by taking the ``ETag`` value of each segment,
concatenating them together, and returning the MD5 checksum of the
result. The manifest object types are:
**Static large objects**
The manifest object content is an ordered list of the names of
the segment objects in JSON format.
**Dynamic large objects**
The manifest object has no content but it has a
``X-Object-Manifest`` metadata header. The value of this header
is ``{container}/{prefix}``, where ``{container}`` is the name of
the container where the segment objects are stored, and
``{prefix}`` is a string that all segment objects have in common.
Note
~~~~
If you make a **COPY** request by using a manifest object as the source,
the new object is a normal, and not a segment, object. If the total size
of the source segment objects exceeds 5 GB, the **COPY** request fails.
However, you can make a duplicate of the manifest object and this new
object can be larger than 5 GB.
Static large objects
~~~~~~~~~~~~~~~~~~~~
To create a static large object, divide your content into pieces and
create (upload) a segment object to contain each piece.
You must record the ``ETag`` response header that the **PUT** operation
returns. Alternatively, you can calculate the MD5 checksum of the
segment prior to uploading and include this in the ``ETag`` request
header. This ensures that the upload cannot corrupt your data.
List the name of each segment object along with its size and MD5
checksum in order.
Create a manifest object. Include the *``?multipart-manifest=put``*
query string at the end of the manifest object name to indicate that
this is a manifest object.
The body of the **PUT** request on the manifest object comprises a json
list, where each element contains the following attributes:
- ``path``. The container and object name in the format:
``{container-name}/{object-name}``
- ``etag``. The MD5 checksum of the content of the segment object. This
value must match the ``ETag`` of that object.
- ``size_bytes``. The size of the segment object. This value must match
the ``Content-Length`` of that object.
**Example Static large object manifest list**
This example shows three segment objects. You can use several containers
and the object names do not have to conform to a specific pattern, in
contrast to dynamic large objects.
.. code::
[
{
"path": "mycontainer/objseg1",
"etag": "0228c7926b8b642dfb29554cd1f00963",
"size_bytes": 1468006
},
{
"path": "mycontainer/pseudodir/seg-obj2",
"etag": "5bfc9ea51a00b790717eeb934fb77b9b",
"size_bytes": 1572864
},
{
"path": "other-container/seg-final",
"etag": "b9c3da507d2557c1ddc51f27c54bae51",
"size_bytes": 256
}
]
|
The ``Content-Length`` request header must contain the length of the
json content—not the length of the segment objects. However, after the
**PUT** operation completes, the ``Content-Length`` metadata is set to
the total length of all the object segments. A similar situation applies
to the ``ETag``. If used in the **PUT** operation, it must contain the
MD5 checksum of the json content. The ``ETag`` metadata value is then
set to be the MD5 checksum of the concatenated ``ETag`` values of the
object segments. You can also set the ``Content-Type`` request header
and custom object metadata.
When the **PUT** operation sees the *``?multipart-manifest=put``* query
parameter, it reads the request body and verifies that each segment
object exists and that the sizes and ETags match. If there is a
mismatch, the **PUT**\ operation fails.
If everything matches, the manifest object is created. The
``X-Static-Large-Object`` metadata is set to ``true`` indicating that
this is a static object manifest.
Normally when you perform a **GET** operation on the manifest object,
the response body contains the concatenated content of the segment
objects. To download the manifest list, use the
*``?multipart-manifest=get``* query parameter. The resulting list is not
formatted the same as the manifest you originally used in the **PUT**
operation.
If you use the **DELETE** operation on a manifest object, the manifest
object is deleted. The segment objects are not affected. However, if you
add the *``?multipart-manifest=delete``* query parameter, the segment
objects are deleted and if all are successfully deleted, the manifest
object is also deleted.
To change the manifest, use a **PUT** operation with the
*``?multipart-manifest=put``* query parameter. This request creates a
manifest object. You can also update the object metadata in the usual
way.
Dynamic large objects
~~~~~~~~~~~~~~~~~~~~~
You must segment objects that are larger than 5 GB before you can upload
them. You then upload the segment objects like you would any other
object and create a dynamic large manifest object. The manifest object
tells Object Storage how to find the segment objects that comprise the
large object. The segments remain individually addressable, but
retrieving the manifest object streams all the segments concatenated.
There is no limit to the number of segments that can be a part of a
single large object.
To ensure the download works correctly, you must upload all the object
segments to the same container and ensure that each object name is
prefixed in such a way that it sorts in the order in which it should be
concatenated. You also create and upload a manifest file. The manifest
file is a zero-byte file with the extra ``X-Object-Manifest``
``{container}/{prefix}`` header, where ``{container}`` is the container
the object segments are in and ``{prefix}`` is the common prefix for all
the segments. You must UTF-8-encode and then URL-encode the container
and common prefix in the ``X-Object-Manifest`` header.
It is best to upload all the segments first and then create or update
the manifest. With this method, the full object is not available for
downloading until the upload is complete. Also, you can upload a new set
of segments to a second location and update the manifest to point to
this new location. During the upload of the new segments, the original
manifest is still available to download the first set of segments.
**Example Upload segment of large object request: HTTP**
.. code::
PUT /{api_version}/{account}/{container}/{object} HTTP/1.1
Host: storage.clouddrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
ETag: 8a964ee2a5e88be344f36c22562a6486
Content-Length: 1
X-Object-Meta-PIN: 1234
No response body is returned. A status code of 2\ *``nn``* (between 200
and 299, inclusive) indicates a successful write; status 411 Length
Required denotes a missing ``Content-Length`` or ``Content-Type`` header
in the request. If the MD5 checksum of the data written to the storage
system does NOT match the (optionally) supplied ETag value, a 422
Unprocessable Entity response is returned.
You can continue uploading segments like this example shows, prior to
uploading the manifest.
**Example Upload next segment of large object request: HTTP**
.. code::
PUT /{api_version}/{account}/{container}/{object} HTTP/1.1
Host: storage.clouddrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
ETag: 8a964ee2a5e88be344f36c22562a6486
Content-Length: 1
X-Object-Meta-PIN: 1234
Next, upload the manifest you created that indicates the container the
object segments reside within. Note that uploading additional segments
after the manifest is created causes the concatenated object to be that
much larger but you do not need to recreate the manifest file for
subsequent additional segments.
**Example Upload manifest request: HTTP**
.. code::
PUT /{api_version}/{account}/{container}/{object} HTTP/1.1
Host: storage.clouddrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
Content-Length: 0
X-Object-Meta-PIN: 1234
X-Object-Manifest: {container}/{prefix}
**Example Upload manifest response: HTTP**
.. code::
[...]
The ``Content-Type`` in the response for a **GET** or **HEAD** on the
manifest is the same as the ``Content-Type`` set during the **PUT**
request that created the manifest. You can easily change the
``Content-Type`` by reissuing the **PUT** request.
Comparison of static and dynamic large objects
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
While static and dynamic objects have similar behavior, here are
their differences:
**Comparing static and dynamic large objects**
Static large object: Assured end-to-end integrity. The list of segments
includes the MD5 checksum (``ETag``) of each segment. You cannot upload the
manifest object if the ``ETag`` in the list differs from the uploaded segment
object. If a segment is somehow lost, an attempt to download the manifest
object results in an error. You must upload the segment objects before you
upload the manifest object. You cannot add or remove segment objects from the
manifest. However, you can create a completely new manifest object of the same
name with a different manifest list.
With static large objects, you can upload new segment objects or remove
existing segments. The names must simply match the ``{prefix}`` supplied
in ``X-Object-Manifest``. The segment objects must be at least 1 MB in size
(by default). The final segment object can be any size. At most, 1000 segments
are supported (by default). The manifest list includes the container name of
each object. Segment objects can be in different containers.
Dynamic large object: End-to-end integrity is not guaranteed. The eventual
consistency model means that although you have uploaded a segment object, it
might not appear in the container listing until later. If you download the
manifest before it appears in the container, it does not form part of the
content returned in response to a **GET** request.
With dynamic large objects, you can upload manifest and segment objects
in any order. In case a premature download of the manifest occurs, we
recommend users upload the manifest object after the segments. However,
the system does not enforce the order. Segment objects can be any size. All
segment objects must be in the same container.
Manifest object metadata
------------------------
For static large objects, the object has ``X-Static-Large-Object`` set to
``true``. You do not set this metadata directly. Instead the system sets
it when you **PUT** a static manifest object.
For dynamic object,s the ``X-Object-Manifest`` value is the
``{container}/{prefix}``, which indicates where the segment objects are
located. You supply this request header in the **PUT** operation.
Copying the manifest object
---------------------------
With static large objects, you include the *``?multipart-manifest=get``*
query string in the **COPY** request. The new object contains the same
manifest as the original. The segment objects are not copied. Instead,
both the original and new manifest objects share the same set of segment
objects.
When creating dynamic large objects, the **COPY** operation does not create
a manifest object. To duplicate a manifest object, use the **GET** operation
to read the value of ``X-Object-Manifest`` and use this value in the
``X-Object-Manifest`` request header in a **PUT** operation. This creates
a new manifest object that shares the same set of segment objects as the
original manifest object.

View File

@ -0,0 +1,182 @@
Object Storage API overview
---------------------------
OpenStack Object Storage is an object-based storage system that stores
content and metadata as objects. You create, modify, and get objects and
metadata by using the Object Storage API, which is implemented as a set
of Representational State Transfer (REST) web services.
For an introduction to OpenStack Object Storage, see `Object
Storage <http://docs.openstack.org/admin-guide-cloud/content/ch_admin-openstack-object-storage.html>`__
in the *OpenStack Cloud Administrator Guide*.
You use the HTTPS (SSL) protocol to interact with Object Storage, and
you use standard HTTP calls to perform API operations. You can also use
language-specific APIs, which use the RESTful API, that make it easier
for you to integrate into your applications.
To assert your right to access and change data in an account, you
identify yourself to Object Storage by using an authentication token. To
get a token, you present your credentials to an authentication service.
The authentication service returns a token and the URL for the account.
Depending on which authentication service that you use, the URL for the
account appears in:
- **OpenStack Identity Service**. The URL is defined in the service
catalog.
- **Tempauth**. The URL is provided in the ``X-Storage-Url`` response
header.
In both cases, the URL is the full URL and includes the account
resource.
The Object Storage API supports the standard, non-serialized response
format, which is the default, and both JSON and XML serialized response
formats.
The Object Storage system organizes data in a hierarchy, as follows:
- **Account**. Represents the top-level of the hierarchy.
Your service provider creates your account and you own all resources
in that account. The account defines a namespace for containers. A
container might have the same name in two different accounts.
In the OpenStack environment, *account* is synonymous with a project
or tenant.
- **Container**. Defines a namespace for objects. An object with the
same name in two different containers represents two different
objects. You can create any number of containers within an account.
In addition to containing objects, you can also use the container to
control access to objects by using an access control list (ACL). You
cannot store an ACL with individual objects.
In addition, you configure and control many other features, such as
object versioning, at the container level.
You can bulk-delete up to 10,000 containers in a single request.
You can set a storage policy on a container with predefined names
and definitions from your cloud provider.
- **Object**. Stores data content, such as documents, images, and so
on. You can also store custom metadata with an object.
With the Object Storage API, you can:
- Store an unlimited number of objects. Each object can be as large
as 5 GB, which is the default. You can configure the maximum
object size.
- Upload and store objects of any size with large object creation.
- Use cross-origin resource sharing to manage object security.
- Compress files using content-encoding metadata.
- Override browser behavior for an object using content-disposition metadata.
- Schedule objects for deletion.
- Bulk-delete up to 10,000 objects in a single request.
- Auto-extract archive files.
- Generate a URL that provides time-limited **GET** access to an
object.
- Upload objects directly to the Object Storage system from a
browser by using form **POST** middleware
The account, container, and object hierarchy affects the way you
interact with the Object Storage API.
Specifically, the resource path reflects this structure and has this
format:
.. code::
/v1/{account}/{container}/{object}
For example, for the ``flowers/rose.jpg`` object in the ``images``
container in the ``12345678912345`` account, the resource path is:
.. code::
/v1/12345678912345/images/flowers/rose.jpg
Notice that the object name contains the ``/`` character. This slash
does not indicate that Object Storage has a sub-hierarchy called
``flowers`` because containers do not store objects in actual
sub-folders. However, the inclusion of ``/`` or a similar convention
inside object names enables you to create pseudo-hierarchical folders
and directories.
For example, if the endpoint for Object Storage is
``objects.mycloud.com``, the returned URL is
``https://objects.mycloud.com/v1/12345678912345``.
To access a container, append the container name to the resource path.
To access an object, append the container and the object name to the
path.
If you have a large number of containers or objects, you can use query
parameters to page through large lists of containers or objects. Use the
*``marker``*, *``limit``*, and *``end_marker``* query parameters to
control how many items are returned in a list and where the list starts
or ends.
Object Storage HTTP requests have the following default constraints.
Your service provider might use different default values.
==== ============= =====
Item Maximum value Notes
==== ============= =====
Number of HTTP headers 90
Length of HTTP headers 4096 bytes
Length per HTTP request line 8192 bytes
Length of HTTP request 5 GB
Length of container names 256 bytes Cannot contain the ``/`` character.
Length of object names 1024 bytes By default, there are no character restrictions.
You must UTF-8-encode and then URL-encode container and object names
before you call the API binding. If you use an API binding that performs
the URL-encoding for you, do not URL-encode the names before you call
the API binding. Otherwise, you double-encode these names. Check the
length restrictions against the URL-encoded string.
The API Reference describes the operations that you can perform with the
Object Storage API:
- `Storage
accounts <http://developer.openstack.org/api-ref-objectstorage-v1.html#storage_account_services>`__:
Use to perform account-level tasks.
Lists containers for a specified account. Creates, updates, and
deletes account metadata. Shows account metadata.
- `Storage
containers <http://developer.openstack.org/api-ref-objectstorage-v1.html#storage_container_services>`__:
Use to perform container-level tasks.
Lists objects in a specified container. Creates, shows details for,
and deletes containers. Creates, updates, shows, and deletes
container metadata.
- `Storage
objects <http://developer.openstack.org/api-ref-objectstorage-v1.html#storage_object_services>`__:
Use to perform object-level tasks.
Creates, replaces, shows details for, and deletes objects. Copies
objects with another object with a new or different name. Updates
object metadata.

View File

@ -0,0 +1,183 @@
=================
Object versioning
=================
You can store multiple versions of your content so that you can recover
from unintended overwrites. Object versioning is an easy way to
implement version control, which you can use with any type of content.
Note
~~~~
You cannot version a large-object manifest file, but the large-object
manifest file can point to versioned segments.
It is strongly recommended that you put non-current objects in a
different container than the container where current object versions
reside.
To enable object versioning, the cloud provider sets the
``allow_versions`` option to ``TRUE`` in the container configuration
file.
The ``X-Versions-Location`` header defines the
container that holds the non-current versions of your objects. You
must UTF-8-encode and then URL-encode the container name before you
include it in the ``X-Versions-Location`` header. This header enables
object versioning for all objects in the container. With a comparable
``archive`` container in place, changes to objects in the ``current``
container automatically create non-current versions in the ``archive``
container.
Here's an example:
#. Create the ``current`` container:
.. code::
# curl -i $publicURL/current -X PUT -H "Content-Length: 0" -H "X-Auth-Token: $token" -H "X-Versions-Location: archive"
.. code::
HTTP/1.1 201 Created
Content-Length: 0
Content-Type: text/html; charset=UTF-8
X-Trans-Id: txb91810fb717347d09eec8-0052e18997
Date: Thu, 23 Jan 2014 21:28:55 GMT
#. Create the first version of an object in the ``current`` container:
.. code::
# curl -i $publicURL/current/my_object --data-binary 1 -X PUT -H "Content-Length: 0" -H "X-Auth-Token: $token"
.. code::
HTTP/1.1 201 Created
Last-Modified: Thu, 23 Jan 2014 21:31:22 GMT
Content-Length: 0
Etag: d41d8cd98f00b204e9800998ecf8427e
Content-Type: text/html; charset=UTF-8
X-Trans-Id: tx5992d536a4bd4fec973aa-0052e18a2a
Date: Thu, 23 Jan 2014 21:31:22 GMT
Nothing is written to the non-current version container when you
initially **PUT** an object in the ``current`` container. However,
subsequent **PUT** requests that edit an object trigger the creation
of a version of that object in the ``archive`` container.
These non-current versions are named as follows:
.. code::
<length><object_name><timestamp>
Where ``length`` is the 3-character, zero-padded hexadecimal
character length of the object, ``<object_name>`` is the object name,
and ``<timestamp>`` is the time when the object was initially created
as a current version.
#. Create a second version of the object in the ``current`` container:
.. code::
# curl -i $publicURL/current/my_object --data-binary 2 -X PUT -H "Content-Length: 0" -H "X-Auth-Token: $token"
.. code::
HTTP/1.1 201 Created
Last-Modified: Thu, 23 Jan 2014 21:41:32 GMT
Content-Length: 0
Etag: d41d8cd98f00b204e9800998ecf8427e
Content-Type: text/html; charset=UTF-8
X-Trans-Id: tx468287ce4fc94eada96ec-0052e18c8c
Date: Thu, 23 Jan 2014 21:41:32 GMT
#. Issue a **GET** request to a versioned object to get the current
version of the object. You do not have to do any request redirects or
metadata lookups.
List older versions of the object in the ``archive`` container:
.. code::
# curl -i $publicURL/archive?prefix=009my_object -X GET -H "X-Auth-Token: $token"
.. code::
HTTP/1.1 200 OK
Content-Length: 30
X-Container-Object-Count: 1
Accept-Ranges: bytes
X-Timestamp: 1390513280.79684
X-Container-Bytes-Used: 0
Content-Type: text/plain; charset=utf-8
X-Trans-Id: tx9a441884997542d3a5868-0052e18d8e
Date: Thu, 23 Jan 2014 21:45:50 GMT
009my_object/1390512682.92052
Note
~~~~
A **POST** request to a versioned object updates only the metadata
for the object and does not create a new version of the object. New
versions are created only when the content of the object changes.
#. Issue a **DELETE** request to a versioned object to remove the
current version of the object and replace it with the next-most
current version in the non-current container.
.. code::
# curl -i $publicURL/current/my_object -X DELETE -H "X-Auth-Token: $token"
.. code::
HTTP/1.1 204 No Content
Content-Length: 0
Content-Type: text/html; charset=UTF-8
X-Trans-Id: tx006d944e02494e229b8ee-0052e18edd
Date: Thu, 23 Jan 2014 21:51:25 GMT
List objects in the ``archive`` container to show that the archived
object was moved back to the ``current`` container:
.. code::
# curl -i $publicURL/archive?prefix=009my_object -X GET -H "X-Auth-Token: $token"
.. code::
HTTP/1.1 204 No Content
Content-Length: 0
X-Container-Object-Count: 0
Accept-Ranges: bytes
X-Timestamp: 1390513280.79684
X-Container-Bytes-Used: 0
Content-Type: text/html; charset=UTF-8
X-Trans-Id: tx044f2a05f56f4997af737-0052e18eed
Date: Thu, 23 Jan 2014 21:51:41 GMT
This next-most current version carries with it any metadata last set
on it. If want to completely remove an object and you have five
versions of it, you must **DELETE** it five times.
#. To disable object versioning for the ``current`` container, remove
its ``X-Versions-Location`` metadata header by sending an empty key
value.
.. code::
# curl -i $publicURL/current -X PUT -H "Content-Length: 0" -H "X-Auth-Token: $token" -H "X-Versions-Location: "
.. code::
HTTP/1.1 202 Accepted
Content-Length: 76
Content-Type: text/html; charset=UTF-8
X-Trans-Id: txe2476de217134549996d0-0052e19038
Date: Thu, 23 Jan 2014 21:57:12 GMT
<html><h1>Accepted</h1><p>The request is accepted for processing.</p></html>

View File

@ -0,0 +1,174 @@
========================
Temporary URL middleware
========================
To discover whether your Object Storage system supports this feature,
check with your service provider or send a **GET** request using the ``/info``
path.
A temporary URL gives users temporary access to objects. For example, a
website might want to provide a link to download a large object in
Object Storage, but the Object Storage account has no public access. The
website can generate a URL that provides time-limited **GET** access to
the object. When the web browser user clicks on the link, the browser
downloads the object directly from Object Storage, eliminating the need
for the website to act as a proxy for the request.
Ask your cloud administrator to enable the temporary URL feature. For
information, see `Temporary
URL <http://docs.openstack.org/havana/config-reference/content/object-storage-tempurl.html>`__
in the *OpenStack Configuration Reference*.
Note
~~~~
To use **POST** requests to upload objects to specific Object Storage
locations, use form **POST** instead of temporary URL middleware. See
`Form POST <http://docs.openstack.org/havana/config-reference/content/object-storage-form-post.html>`__
in the *OpenStack Configuration Reference*.
Temporary URL format
~~~~~~~~~~~~~~~~~~~~
A temporary URL is comprised of the URL for an object with added query
parameters:
**Example Temporary URL format**
.. code::
https://swift-cluster.example.com/v1/my_account/container/object
?temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709
&temp_url_expires=1323479485
&filename=My+Test+File.pdf
The example shows these elements:
**Object URL**: Required. The full path URL to the object.
**temp\_url\_sig**: Required. An HMAC-SHA1 cryptographic signature that defines
the allowed HTTP method, expiration date, full path to the object, and the
secret key for the temporary URL.
**temp\_url\_expires**: Required. An expiration date as a UNIX Epoch timestamp,
which is an integer value. For example, ``1390852007`` represents
``Mon, 27 Jan 2014 19:46:47 GMT``.
For more information, see `Epoch & Unix Timestamp Conversion
Tools <http://www.epochconverter.com/>`__.
**filename**: Optional. Overrides the default file name. Object Storage
generates a default file name for **GET** temporary URLs that is based on the
object name. Object Storage returns this value in the ``Content-Disposition``
response header. Browsers can interpret this file name value as a file
attachment to be saved.
Account secret keys
~~~~~~~~~~~~~~~~~~~
Object Storage supports up to two secret keys. You set secret keys at
the account level.
To set these keys, set one or both of the following request headers to
arbitrary values:
- ``X-Account-Meta-Temp-URL-Key``
- ``X-Account-Meta-Temp-URL-Key-2``
The arbitrary values serve as the secret keys.
Object Storage checks signatures against both keys, if present, to
enable key rotation without invalidating existing temporary URLs.
For example, use the **swift post** command to set the secret key to
*``MYKEY``*:
.. code::
$ swift post -m "Temp-URL-Key:MYKEY"
Note
~~~~
Changing these headers invalidates any previously generated temporary
URLs within 60 seconds, which is the memcache time for the key.
HMAC-SHA1 signature for temporary URLs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Temporary URL middleware uses an HMAC-SHA1 cryptographic signature. This
signature includes these elements:
- The allowed method. Typically, **GET** or **PUT**.
- Expiry time. In the example for the HMAC-SHA1 signature for temporary
URLs below, the expiry time is set to ``86400`` seconds (or 1 day)
into the future.
- The path. Starting with ``/v1/`` onwards and including a container
name and object. In the example below, the path is
``/v1/my_account/container/object``. Do not URL-encode the path at
this stage.
- The secret key. Set as the ``X-Account-Meta-Temp-URL-Key`` header
value.
This sample Python code shows how to compute a signature for use with
temporary URLs:
**Example HMAC-SHA1 signature for temporary URLs**
.. code::
import hmac
from hashlib import sha1
from time import time
method = 'GET'
duration_in_seconds = 60*60*24
expires = int(time() + duration_in_seconds)
path = '/v1/my_account/container/object'
key = 'MYKEY'
hmac_body = '%s\n%s\n%s' % (method, expires, path)
signature = hmac.new(key, hmac_body, sha1).hexdigest()
Do not URL-encode the path when you generate the HMAC-SHA1 signature.
However, when you make the actual HTTP request, you should properly
URL-encode the URL.
The *``MYKEY``* value is the value you set in the
``X-Account-Meta-Temp-URL-Key`` request header on the account.
For more information, see `RFC 2104: HMAC: Keyed-Hashing for Message
Authentication <http://www.ietf.org/rfc/rfc2104.txt>`__.
swift-temp-url script
~~~~~~~~~~~~~~~~~~~~~
Object Storage provides the **swift-temp-url** script that
auto-generates the *``temp_url_sig``* and *``temp_url_expires``* query
parameters. For example, you might run this command:
.. code::
$ bin/swift-temp-url GET 3600 /v1/my_account/container/object MYKEY
This command returns the path:
.. code::
/v1/my_account/container/object
?temp_url_sig=5c4cc8886f36a9d0919d708ade98bf0cc71c9e91
&temp_url_expires=1374497657
To create the temporary URL, prefix this path with the Object Storage
storage host name. For example, prefix the path with
``https://swift-cluster.example.com``, as follows:
.. code::
https://swift-cluster.example.com/v1/my_account/container/object
?temp_url_sig=5c4cc8886f36a9d0919d708ade98bf0cc71c9e91
&temp_url_expires=1374497657

View File

@ -0,0 +1,22 @@
=============================
Use Content-Encoding metadata
=============================
When you create an object or update its metadata, you can optionally set
the ``Content-Encoding`` metadata. This metadata enables you to indicate
that the object content is compressed without losing the identity of the
underlying media type (``Content-Type``) of the file, such as a video.
**Example Content-Encoding header request: HTTP**
This example assigns an attachment type to the ``Content-Encoding``
header that indicates how the file is downloaded:
.. code::
PUT /<api version>/<account>/<container>/<object> HTTP/1.1
Host: storage.clouddrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
Content-Type: video/mp4
Content-Encoding: gzip

View File

@ -0,0 +1,30 @@
====================================
Use the Content-Disposition metadata
====================================
To override the default behavior for a browser, use the
``Content-Disposition`` header to specify the override behavior and
assign this header to an object. For example, this header might specify
that the browser use a download program to save this file rather than
show the file, which is the default.
**Example Override browser default behavior request: HTTP**
This example assigns an attachment type to the ``Content-Disposition``
header. This attachment type indicates that the file is to be downloaded
as ``goodbye.txt``:
.. code::
# curl -i $publicURL/marktwain/goodbye -X POST -H "X-Auth-Token: $token" -H "Content-Length: 14" -H "Content-Type: application/octet-stream" -H "Content-Disposition: attachment; filename=goodbye.txt"
.. code::
HTTP/1.1 202 Accepted
Content-Length: 76
Content-Type: text/html; charset=UTF-8
X-Trans-Id: txa9b5e57d7f354d7ea9f57-0052e17e13
Date: Thu, 23 Jan 2014 20:39:47 GMT
<html><h1>Accepted</h1><p>The request is accepted for processing.</p></html>

View File

@ -42,7 +42,7 @@ Overview and Concepts
.. toctree::
:maxdepth: 1
Swift's API docs <http://docs.openstack.org/api/openstack-object-storage/1.0/content/>
api/object_api_v1_overview
overview_architecture
overview_ring
overview_policies
@ -84,6 +84,24 @@ Administrator Documentation
replication_network
logs
Object Storage v1 REST API Documentation
========================================
.. toctree::
:maxdepth: 1
api/object_api_v1_overview.rst
api/discoverability.rst
api/authentication.rst
api/container_quotas.rst
api/object_versioning.rst
api/large_objects.rst
api/temporary_url_middleware.rst
api/form_post_middleware.rst
api/use_content-encoding_metadata.rst
api/use_the_content-disposition_metadata.rst
Source Documentation
====================