Updated Object Storage API Guide with examples chunked

bug: #968392

Also updates pom.xml to version 1.7.2.

Change-Id: Ieaf93dbcf3c46d638f09fc9e84374bdaa042ee3b
author: Diane Fleming
This commit is contained in:
Diane Fleming
2013-02-22 15:32:01 -06:00
committed by annegentle
parent 3396b60d56
commit 395a4357ca
84 changed files with 2318 additions and 2027 deletions

View File

@@ -50,7 +50,7 @@
<plugin>
<groupId>com.rackspace.cloud.api</groupId>
<artifactId>clouddocs-maven-plugin</artifactId>
<version>1.5.2</version>
<version>1.7.2</version>
<executions>
<execution>
<id>goal1</id>
@@ -90,24 +90,11 @@
<!-- The following elements sets the autonumbering of sections in output for chapter numbers but no numbered sections-->
<!--<sectionAutolabel>0</sectionAutolabel>
<sectionLabelIncludesComponentLabel>0</sectionLabelIncludesComponentLabel>-->
<targetDirectory>target/docbkx/webhelp/openstack-object-storage</targetDirectory>
<webhelpDirname>1.0</webhelpDirname>
<pdfFilenameBase>bk-objectstorage-devguide-1.0</pdfFilenameBase>
<postProcess>
<!-- Copies the figures to the correct location for webhelp -->
<!-- No figures in this book -->
<!-- Copies HTML to a release folder --> <copy
todir="${basedir}/target/docbkx/webhelp/api/openstack-object-storage/1.0">
<fileset
dir="${basedir}/target/docbkx/webhelp/os-objectstorage-devguide">
<include name="**/*" />
</fileset>
</copy>
<!--Moves PDFs to the needed placement -->
<move failonerror="false"
file="${basedir}/target/docbkx/pdf/os-objectstorage-devguide.pdf"
tofile="${basedir}/target/docbkx/webhelp/api/openstack-object-storage/1.0/os-objectstorage-devguide-1.0.pdf"/>
<!-- Removes unnecessary copy of the guide output -->
<delete
dir="${basedir}/target/docbkx/webhelp/os-objectstorage-devguide"/>
</postProcess>

View File

@@ -0,0 +1,128 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section [
<!-- Some useful entities borrowed from HTML -->
<!ENTITY ndash "&#x2013;">
<!ENTITY mdash "&#x2014;">
<!ENTITY hellip "&#x2026;">
<!-- Useful for describing APIs -->
<!ENTITY COPY '<command xmlns="http://docbook.org/ns/docbook">COPY</command>'>
<!ENTITY GET '<command xmlns="http://docbook.org/ns/docbook">GET</command>'>
<!ENTITY HEAD '<command xmlns="http://docbook.org/ns/docbook">HEAD</command>'>
<!ENTITY PUT '<command xmlns="http://docbook.org/ns/docbook">PUT</command>'>
<!ENTITY POST '<command xmlns="http://docbook.org/ns/docbook">POST</command>'>
<!ENTITY DELETE '<command xmlns="http://docbook.org/ns/docbook">DELETE</command>'>
<!ENTITY CHECK '<inlinemediaobject xmlns="http://docbook.org/ns/docbook">
<imageobject>
<imagedata fileref="img/Check_mark_23x20_02.svg"
format="SVG" scale="60"/>
</imageobject>
</inlinemediaobject>'>
<!ENTITY ARROW '<inlinemediaobject xmlns="http://docbook.org/ns/docbook">
<imageobject>
<imagedata fileref="img/Arrow_east.svg"
format="SVG" scale="60"/>
</imageobject>
</inlinemediaobject>'>
]>
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0"
xml:id="Create_Static_Website-dle4000">
<title>Create Static Website</title>
<para>You can use your swift account to create a static website.
This mode is normally only active for anonymous requests. To
use it with authenticated requests, set the header
<code>X-Web-Mode</code> to <code>TRUE</code> on the
request. The <code>staticweb</code> filter should be added to
the pipeline in your <code>/etc/swift/proxy-server.conf</code>
file just after any auth middleware. Beneath the pipeline, the
<code>staticweb</code> middleware configuration must be
added. For example:
<literallayout class="monospaced"><xi:include href="samples/proxy-server-excerpt.conf" parse="text"/></literallayout>
Your publicly readable containers will be checked for two
headers, <code>X-Container-Meta-Web-Index</code> and
<code>X-Container-Meta-Web-Error</code>. (The latter
header is discussed below, under <link
linkend="Set_Error_Pages_for_Static_Website-dle4005">Set
Error Pages for Static Website</link>.) With
<code>X-Container-Meta-Web-Index</code>, you determine the
index file (or default page served, such as
<code>index.html</code>) displays your website. When
someone initially enters your site, they don't have to specify
the index file; index.html file displays automatically. If you
create sub-directories for your site--which you do by creating
pseudo-directories in your container--the index page displays
by default for each sub-directory. If your pseduo-directory
does not have a file with the same name as your index file,
visits to the sub-directory return a 404 error. </para>
<para> You also have the option of displaying a list of files in
your pseudo-directory instead of a web page. You do this by
setting the <code>X-Container-Meta-Web-Listings</code> header
to <code>TRUE</code>. You may add style to your file listing
by setting <code>X-Container-Meta-Web-Listings-CSS:</code> to
a stylesheet (i.e., <code>lists.css</code>). </para>
<section xml:id="Examples_for_static_web-dle4025">
<title>Static Web Middleware through swift</title>
<example>
<title>Make Container Publicly Readable</title>
<para> Make the container publicly readable. Once the
container is publicly readable, you may access your
objects directly, but you will need to set the index
file to browse the main site URL and its
sub-directories. </para>
<literallayout class="monospaced">swift post -r '.r:*' container</literallayout>
</example>
<example>
<title>Set Site Index File</title>
<para>Set the index file. In this case,
<code>index.html</code> is the default file
displayed when the site displays. </para>
<literallayout class="monospaced">swift post -m 'web-index:index.html' container</literallayout>
</example>
<example>
<title>Enable File Listing</title>
<para>Turn on file listing. If you do not set the index
file, list the objects in the container. Instructions
on styling the list with the CSS follow. </para>
<literallayout class="monospaced">swift post -m 'web-listings: true' container</literallayout>
</example>
<example>
<title>Enable CSS for File Listing</title>
<para>Style the file listing. </para>
<literallayout class="monospaced"><xi:include href="samples/file-listings-css-set-req.txt" parse="text"/></literallayout>
</example>
</section>
<section xml:id="Set_Error_Pages_for_Static_Website-dle4005">
<title>Set Error Pages for Static Website</title>
<para>You can create and set custom error pages for visitors
to your website; currently, only 401 (Unauthorized) and
404 (Not Found) errors are supported. To do this, set the
metadata header, <code>X-Container-Meta-Web-Error</code>. </para>
<para> Error pages are served with the &lt;status&gt; code
pre-pended to the name of the error page you set. For
instance, if you set
<code>X-Container-Meta-Web-Error</code> to
<code>error.html</code>, 401 errors will display the
page <code>401error.html</code>. Similarly, 404 errors
will display <code>404error.html</code>. You must have
both of these pages created in your container when you set
the <code>X-Container-Meta-Web-Error</code> metadata, or
your site will display generic error pages. </para>
<para>Set the <code>X-Container-Meta-Web-Error</code> metadata
once for your entire static website. </para>
<example>
<title>Set Error Pages for Static Website Request</title>
<literallayout class="monospaced"><xi:include href="samples/error-page-set-req.txt" parse="text"/></literallayout>
</example>
<para> Any 2<varname>xx</varname> response indicates success.
</para>
</section>
</section>

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter [
<!-- Some useful entities borrowed from HTML -->
<!ENTITY ndash "&#x2013;">
<!ENTITY mdash "&#x2014;">
<!ENTITY hellip "&#x2026;">
<!-- Useful for describing APIs -->
<!ENTITY GET '<command xmlns="http://docbook.org/ns/docbook">GET</command>'>
<!ENTITY PUT '<command xmlns="http://docbook.org/ns/docbook">PUT</command>'>
<!ENTITY POST '<command xmlns="http://docbook.org/ns/docbook">POST</command>'>
<!ENTITY DELETE '<command xmlns="http://docbook.org/ns/docbook">DELETE</command>'>
<!ENTITY CHECK '<inlinemediaobject xmlns="http://docbook.org/ns/docbook">
<imageobject>
<imagedata fileref="img/Check_mark_23x20_02.svg"
format="SVG" scale="60"/>
</imageobject>
</inlinemediaobject>'>
<!ENTITY ARROW '<inlinemediaobject xmlns="http://docbook.org/ns/docbook">
<imageobject>
<imagedata fileref="img/Arrow_east.svg"
format="SVG" scale="60"/>
</imageobject>
</inlinemediaobject>'>
]>
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0"
xml:id="doc_history">
<title>Document Change History</title>
<para>This version of the guide was forked from the <citetitle>Rackspace Cloud Files Developer
Guide</citetitle>.
</para>
<!-- *** -->
<?rax revhistory?>
<!-- *** -->
</chapter>

View File

@@ -31,235 +31,163 @@ format="SVG" scale="60"/>
xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0"
xml:id="ch_object-storage-dev-general-api">
<title>General API Information</title>
<para>API Operations Reference Summary</para>
<para> Storage Accounts </para>
<informaltable rules="all">
<thead>
<tr>
<td colspan="1">Verb</td>
<td colspan="2">URI</td>
<td colspan="3">Description</td>
</tr>
</thead>
<tbody>
<tr>
<td colspan="1">&GET;</td>
<td colspan="2">/<parameter>account</parameter></td>
<td colspan="3">List containers</td>
</tr>
<tr>
<td colspan="1">&HEAD;</td>
<td colspan="2"><parameter>account</parameter></td>
<td colspan="3">Retrieve account metadata</td>
</tr>
</tbody>
</informaltable>
<para> Storage Containers </para>
<informaltable rules="all">
<thead>
<tr>
<td colspan="1">Verb</td>
<td colspan="2">URI</td>
<td colspan="3">Description</td>
</tr>
</thead>
<tbody>
<tr>
<td colspan="1">&GET;</td>
<td colspan="2">/<parameter>account</parameter>/<parameter>container</parameter></td>
<td colspan="3">List objects</td>
</tr>
<tr>
<td colspan="1">&PUT;</td>
<td colspan="2">/<parameter>account</parameter>/<parameter>container</parameter></td>
<td colspan="3">Create container</td>
</tr>
<tr>
<td colspan="1">&DELETE;</td>
<td colspan="2">/<parameter>account</parameter>/<parameter>container</parameter></td>
<td colspan="3">Delete container</td>
</tr>
<tr>
<td colspan="1">&HEAD;</td>
<td colspan="2">/<parameter>account</parameter>/<parameter>container</parameter></td>
<td colspan="3">Retrieve container metadata</td>
</tr>
</tbody>
</informaltable>
<para> Storage Objects </para>
<informaltable rules="all">
<thead>
<tr>
<td colspan="1">Verb</td>
<td colspan="2">URI</td>
<td colspan="3">Description</td>
</tr>
</thead>
<tbody>
<tr>
<td colspan="1">&GET;</td>
<td colspan="2"
>/<parameter>account</parameter>/<parameter>container</parameter>/<parameter>object</parameter></td>
<td colspan="3">Retrieve object</td>
</tr>
<tr>
<td colspan="1">&PUT;</td>
<td colspan="2"
>/<parameter>account</parameter>/<parameter>container</parameter>/<parameter>object</parameter></td>
<td colspan="3">Create/Update Object</td>
</tr>
<tr>
<td colspan="1">&PUT;</td>
<td colspan="2"
>/<parameter>account</parameter>/<parameter>container</parameter>/<parameter>object</parameter></td>
<td colspan="3">Chunked transfer encoding</td>
</tr>
<tr>
<td colspan="1">&DELETE;</td>
<td colspan="2"
>/<parameter>account</parameter>/<parameter>container</parameter>/<parameter>object</parameter></td>
<td colspan="3">Delete container</td>
</tr>
<tr>
<td colspan="1">&HEAD;</td>
<td colspan="2"
>/<parameter>account</parameter>/<parameter>container</parameter>/<parameter>object</parameter></td>
<td colspan="3">Retrieve object metadata</td>
</tr>
<tr>
<td colspan="1">&POST;</td>
<td colspan="2"
>/<parameter>account</parameter>/<parameter>container</parameter>/<parameter>object</parameter></td>
<td colspan="3">Update object metadata</td>
</tr>
</tbody>
</informaltable>
<section xml:id="authentication-object-dev-guide">
<title>Authentication</title>
<para>Client authentication is provided via a ReST interface using the &GET;
method, with <code>v1.0</code> supplied as the path. Additionally, two headers are required,
<code>X-Auth-User</code> and <code>X-Auth-Key</code> with values for the username and API
Access Key respectively.</para>
<para> Each ReST request against the OpenStack Object Storage system requires the inclusion of
a specific authorization token HTTP x-header, defined as <code>X-Auth-Token</code>.
Clients obtain this token, along with the Cloud Servers API URL, by first using an
authentication service and supplying a valid username and API access key. </para>
<para>Client authentication is provided via a ReST interface
using the &GET; method, with <code>v1.0</code> supplied as
the path. Additionally, two headers are required,
<code>X-Auth-User</code> and <code>X-Auth-Key</code>
with values for the username and API Access Key
respectively.</para>
<para>Each ReST request against the OpenStack Object Storage
system requires the inclusion of a specific authorization
token HTTP x-header, defined as <code>X-Auth-Token</code>.
Clients obtain this token, along with the Cloud Servers
API URL, by first using an authentication service and
supplying a valid username and API access key. </para>
<simplesect>
<title>Request</title>
<para>
To authenticate, you must supply your username and API access key in x-headers:
</para>
<para>To authenticate, you must supply your username and
API access key in x-headers: </para>
<para>
<itemizedlist spacing="compact">
<listitem>
<para> Use your OpenStack Object Storage (Swift) username as the username for the API.
Place it in the <code>X-Auth-User</code> x-header. </para>
<para>Use your OpenStack Object Storage
(Swift) username as the username for the
API. Place it in the
<code>X-Auth-User</code> x-header.
</para>
</listitem>
<listitem>
<para> Obtain your API access key from authentication service you chose when
installing. You have some options for auth, including tempauth (which is
included with Swift), swauth (an auth service for Swift as WSGI middleware that uses
Swift itself as a backing store that is provided via download from Github),
the OpenStack Identity Service (project named Keystone), or you can use your own
authentication system. Place your access key in the <code>X-Auth-Key</code> x-header. </para>
<para>Get your API access key from
authentication service you chose when
installing. You have some options for
auth, including tempauth (which is
included with Swift), swauth (an auth
service for Swift as WSGI middleware that
uses Swift itself as a backing store that
is provided via download from Github), the
OpenStack Identity Service (project named
Keystone), or you can use your own
authentication system. Place your access
key in the <code>X-Auth-Key</code>
x-header. </para>
</listitem>
</itemizedlist>
</para>
<para> </para>
<example>
<title>Authentication Request </title>
<literallayout class="monospaced">
GET /v1.0 HTTP/1.1
Host: auth.api.yourcloud.com
X-Auth-User: jdoe
X-Auth-Key: a86850deb2742ec3cb41518e26aa2d89
</literallayout>
<title>Authentication HTTP Request </title>
<literallayout class="monospaced"><xi:include href="samples/auth-req.txt" parse="text"/></literallayout>
</example>
</simplesect>
<simplesect>
<title>Response</title>
<para>When authentication is successful, an HTTP status 204 (No Content) is returned with
the <code>X-Storage-Url</code> and
<code>X-Auth-Token</code> headers. Any 2xx response is a good response.
For example, a 202 response means the request has been accepted.
Also, additional <code>X-</code> headers
may be returned. These additional headers are related to other Rackspace services and can
be ignored. An HTTP status of 401 (Unauthorized) is returned upon authentication failure.
All subsequent container/object operations against OpenStack Object Storage should be made
against the URI specified in <code>X-Storage-Url</code> and must include the <code>X-Auth-Token</code>
header.</para>
<title>Response</title>
<para>When authentication is successful, an HTTP status
204 (No Content) is returned with the
<code>X-Storage-Url</code> and
<code>X-Auth-Token</code> headers. Any 2xx
response is a good response. For example, a 202
response means the request has been accepted. Also,
additional <code>X-</code> headers may be returned.
These additional headers are related to other
Rackspace services and can be ignored. An HTTP status
of 401 (Unauthorized) is returned upon authentication
failure. All subsequent container/object operations
against OpenStack Object Storage should be made
against the URI specified in
<code>X-Storage-Url</code> and must include the
<code>X-Auth-Token</code> header.</para>
<example>
<title>Authentication Response</title>
<literallayout class="monospaced">
HTTP/1.1 204 No Content
Date: Mon, 12 Nov 2010 15:32:21 GMT
Server: Apache
X-Storage-Url: https://storage.swiftdrive.com/v1/CF_xer7_34
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
Content-Length: 0
Content-Type: text/plain; charset=UTF-8
</literallayout>
<title>Authentication HTTP Response</title>
<literallayout class="monospaced"><xi:include href="samples/auth-resp.txt" parse="text"/></literallayout>
</example>
<para>The <code>X-Storage-Url</code> will need to be parsed and used in the
connection and request line of all subsequent requests against Object Storage. In the example
response above, users connecting to OpenStack Object Storage would send most
container/object requests with a host header of <code>storage.swiftdrive.com</code> and
the request line's version and account as <code>/v1/CF_xer7_34</code>. Note that
authentication tokens are valid for a 24 hour period for many authentication configurations.</para>
<para>The <code>X-Storage-Url</code> will need to be
parsed and used in the connection and request line of
all subsequent requests against Object Storage. In the
example response above, users connecting to OpenStack
Object Storage would send most container/object
requests with a host header of
<code>storage.swiftdrive.com</code> and the
request line's version and account as
<code>/v1/CF_xer7_34</code>. Note that
authentication tokens are valid for a 24 hour period
for many authentication configurations.</para>
</simplesect>
</section>
<section xml:id="overview-object-api">
<title>Overview of API Operations</title>
<para>The OpenStack Object Storage API is implemented as a set of ReSTful (Representational State Transfer)
web services. All authentication and container/object operations can be performed with
standard HTTP calls. See the <link xlink:href="http://en.wikipedia.org/wiki/Representational_State_Transfer">Wikipedia
article</link> on ReST for more information</para>
<para>The following constraints apply to the ReST API's HTTP requests:</para>
<para>The OpenStack Object Storage API is implemented as a set
of ReSTful (Representational State Transfer) web services.
All authentication and container/object operations can be
performed with standard HTTP calls. See the <link
xlink:href="http://en.wikipedia.org/wiki/Representational_State_Transfer"
>Wikipedia article</link> on ReST for more
information</para>
<para>The following constraints apply to the ReST API's HTTP
requests:</para>
<itemizedlist>
<listitem>
<para>Maximum number of HTTP headers per request: 90</para>
<para>Maximum number of HTTP headers per request:
90</para>
</listitem>
<listitem>
<para>Maximum length of all HTTP headers: 4096 bytes</para>
<para>Maximum length of all HTTP headers: 4096
bytes</para>
</listitem>
<listitem>
<para>Maximum length per HTTP request line: 8192 bytes</para>
<para>Maximum length per HTTP request line: 8192
bytes</para>
</listitem>
<listitem>
<para>Maximum length of HTTP request: 5 gigabytes</para>
<para>Maximum length of HTTP request: 5
gigabytes</para>
</listitem>
<listitem>
<para>Maximum length of container name: 256 bytes</para>
<para>Maximum length of container name: 256
bytes</para>
</listitem>
<listitem>
<para>Maximum length of object name: 1024 bytes</para>
</listitem>
</itemizedlist>
<para>Container and object names should be properly URL-encoded prior to interacting with the
ReST interface (the language APIs handle URL encoding/decoding) and the container
and object names must be UTF-8 encoded. The length restrictions should be checked
against the URL-encoded string.</para>
<para>Each ReST request against the OpenStack Object Storage system requires the inclusion of a specific
<firstterm>authorization token</firstterm> HTTP header defined as <code>X-Auth-Token</code>.
Clients obtain this token, along with the OpenStack Object Storage URLs, by first using the Authentication
service and supplying a valid Username and API Access Key.</para>
<para>Container and object names should be properly
URL-encoded prior to interacting with the ReST interface
(the language APIs handle URL encoding/decoding) and the
container and object names must be UTF-8 encoded. The
length restrictions should be checked against the
URL-encoded string.</para>
<para>Each ReST request against the OpenStack Object Storage
system requires the inclusion of a specific
<firstterm>authorization token</firstterm> HTTP header
defined as <code>X-Auth-Token</code>. Clients obtain this
token, along with the OpenStack Object Storage URLs, by
first using the Authentication service and supplying a
valid Username and API Access Key.</para>
<para><!--There are actually two different sets of ReST services that make up the full OpenStack Object Storage product. -->
The ReST service identified with <code>X-Storage-Url</code> is used for managing the data stored
in the system. Example operations are creating containers and uploading objects.
The ReST service identified with
<code>X-Storage-Url</code> is used for managing the
data stored in the system. Example operations are creating
containers and uploading objects.
<!--The second ReST service is for managing the CDN feature of OpenStack Object Storage and is identified by <code>X-CDN-Management-Url</code>.--></para>
<para>In the following sections, the purpose of each HTTP method depends upon which service the
call is made against. For example, a &PUT; request against <code>X-Storage-Url</code> can be
used to create a container or upload an
object<!--, while a &PUT; request against the <code>X-CDN-Management-Url</code> is used to CDN-enable a container-->.</para>
<para>The language-specific APIs mask this system separation from the programmer. They simply
create a container and mark it <emphasis>public</emphasis> and it handles calling out to the
appropriate back-end services using the appropriate ReST API.</para>
<para>In the following sections, the purpose of each HTTP
method depends upon which service the call is made
against. For example, a &PUT; request against
<code>X-Storage-Url</code> can be used to create a
container or upload an
object.<!--, while a &PUT; request against the <code>X-CDN-Management-Url</code> is used to CDN-enable a container--></para>
<para>The language-specific APIs mask this system separation
from the programmer. They simply create a container and
mark it <emphasis>public</emphasis> and it handles calling
out to the appropriate back-end services using the
appropriate ReST API.</para>
<note>
<para>All requests to authenticate and operate against OpenStack Object Storage are performed using SSL
over HTTP (HTTPS) on TCP port 443.</para>
<para>All requests to authenticate and operate against
OpenStack Object Storage are performed using SSL over
HTTP (HTTPS) on TCP port 443.</para>
</note>
</section>
</chapter>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter [
<!DOCTYPE preface [
<!-- Some useful entities borrowed from HTML -->
<!ENTITY ndash "&#x2013;">
<!ENTITY mdash "&#x2014;">
@@ -25,29 +25,33 @@ format="SVG" scale="60"/>
</imageobject>
</inlinemediaobject>'>
]>
<chapter xmlns="http://docbook.org/ns/docbook"
<preface xmlns="http://docbook.org/ns/docbook"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0"
xml:id="ch_object-storage-dev-overview">
<title>Overview</title>
<para>OpenStack Object Storage is an affordable, redundant, scalable, and dynamic storage
service offering. The core storage system is designed to provide a safe, secure,
automatically re-sizing and network-accessible way to store data. You can store an
unlimited quantity of files and each file can be as large as 5 gigabytes, plus with
large object creation, you can upload and store objects of virtually any size.
</para>
<para>OpenStack Object Storage allows users to store and retrieve files and content via a simple
Web Service inteface (ReST: Representational State Transfer). There are also
language-specific APIs that utilize the ReSTful API but make it much easier for
developers to integrate into their applications.</para>
<para>OpenStack Object Storage is an affordable, redundant,
scalable, and dynamic storage service offering. The core
storage system is designed to provide a safe, secure,
automatically re-sizing and network-accessible way to store
data. You can store an unlimited quantity of files and each
file can be as large as 5 GBs, plus with large object
creation, you can upload and store objects of virtually any
size. </para>
<para>OpenStack Object Storage allows users to store and retrieve
files and content through a simple Web Service interface
(ReST: Representational State Transfer). There are also
language-specific APIs that utilize the ReSTful API but make
it much easier for developers to integrate into their
applications.</para>
<para>For more details on the OpenStack Object Storage service, please refer to <link
xlink:href="http://swift.openstack.org"
>http://swift.openstack.org</link>
</para>
<para> We welcome feedback, comments, and bug reports at <link
xlink:href="http://bugs.launchpad.net/swift">http://bugs.launchpad.net/swift</link>.
</para>
<para>We welcome feedback, comments, and bug reports at <link
xlink:href="http://bugs.launchpad.net/swift"
>http://bugs.launchpad.net/swift</link>. </para>
<section xml:id="intended-audience-object-dev-guide">
<title>Intended Audience</title>
<para>This guide is intended to assist software developers who want to develop applications
@@ -72,32 +76,5 @@ format="SVG" scale="60"/>
its native format. For example, the Java API includes JavaDocs and the C#/.NET API
includes a CHM file.</para>
</section>
<section xml:id="doc-change-history-object-dev-guide">
<title>Document Change History</title>
<para>This version of the Developer Guide was forked from the Rackspace Cloud Files Developer
Guide.
</para>
<!-- *** -->
<?rax revhistory?>
<!-- *** -->
</section>
<section xml:id="additional-resources-object-devguide">
<title>Additional Resources</title>
<para>You can download the most current version of this document from the OpenStack Docs
website at <link
xlink:href="http://docs.openstack.org">
http://docs.openstack.org</link>. </para>
<para>
If you would like more information about the Rackspace implementation of
the OpenStack Object Storage service, visit this address:
<link xlink:href="www.rackspacecloud.com/cloud_hosting_products/files">
http://www.rackspacecloud.com/cloud_hosting_products/files</link>. Related documents are
available at the same site, as are links to Rackspace's official support channels, including
knowledge base articles, forums, phone, chat, and email. </para>
</section>
</chapter>
</preface>

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter [
<!-- Some useful entities borrowed from HTML -->
<!ENTITY ndash "&#x2013;">
<!ENTITY mdash "&#x2014;">
<!ENTITY hellip "&#x2026;">
<!-- Useful for describing APIs -->
<!ENTITY GET '<command xmlns="http://docbook.org/ns/docbook">GET</command>'>
<!ENTITY PUT '<command xmlns="http://docbook.org/ns/docbook">PUT</command>'>
<!ENTITY POST '<command xmlns="http://docbook.org/ns/docbook">POST</command>'>
<!ENTITY DELETE '<command xmlns="http://docbook.org/ns/docbook">DELETE</command>'>
<!ENTITY CHECK '<inlinemediaobject xmlns="http://docbook.org/ns/docbook">
<imageobject>
<imagedata fileref="img/Check_mark_23x20_02.svg"
format="SVG" scale="60"/>
</imageobject>
</inlinemediaobject>'>
<!ENTITY ARROW '<inlinemediaobject xmlns="http://docbook.org/ns/docbook">
<imageobject>
<imagedata fileref="img/Arrow_east.svg"
format="SVG" scale="60"/>
</imageobject>
</inlinemediaobject>'>
]>
<chapter xmlns="http://docbook.org/ns/docbook"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0"
xml:id="additional-resources-object-devguide">
<title>Additional Resources</title>
<para>You can download the most current version of this document from the OpenStack Docs
website at <link
xlink:href="http://docs.openstack.org">
http://docs.openstack.org</link>. </para>
<para>For more information about the Rackspace implementation of
the OpenStack Object Storage service, see:
<link xlink:href="www.rackspacecloud.com/cloud_hosting_products/files">
http://www.rackspacecloud.com/cloud_hosting_products/files</link>. Related documents are
available at the same site, as are links to Rackspace's official support channels, including
knowledge base articles, forums, phone, chat, and email. </para>
</chapter>

View File

@@ -0,0 +1,501 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section [
<!-- Some useful entities borrowed from HTML -->
<!ENTITY ndash "&#x2013;">
<!ENTITY mdash "&#x2014;">
<!ENTITY hellip "&#x2026;">
<!-- Useful for describing APIs -->
<!ENTITY COPY '<command xmlns="http://docbook.org/ns/docbook">COPY</command>'>
<!ENTITY GET '<command xmlns="http://docbook.org/ns/docbook">GET</command>'>
<!ENTITY HEAD '<command xmlns="http://docbook.org/ns/docbook">HEAD</command>'>
<!ENTITY PUT '<command xmlns="http://docbook.org/ns/docbook">PUT</command>'>
<!ENTITY POST '<command xmlns="http://docbook.org/ns/docbook">POST</command>'>
<!ENTITY DELETE '<command xmlns="http://docbook.org/ns/docbook">DELETE</command>'>
<!ENTITY CHECK '<inlinemediaobject xmlns="http://docbook.org/ns/docbook">
<imageobject>
<imagedata fileref="img/Check_mark_23x20_02.svg"
format="SVG" scale="60"/>
</imageobject>
</inlinemediaobject>'>
<!ENTITY ARROW '<inlinemediaobject xmlns="http://docbook.org/ns/docbook">
<imageobject>
<imagedata fileref="img/Arrow_east.svg"
format="SVG" scale="60"/>
</imageobject>
</inlinemediaobject>'>
]>
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0"
xml:id="storage-container-services">
<title>Storage Container Services</title>
<para>You can perform the following operations for
containers:</para>
<informaltable rules="all">
<thead>
<tr>
<td colspan="1">Verb</td>
<td colspan="2">URI</td>
<td colspan="3">Description</td>
</tr>
</thead>
<tbody>
<tr>
<td colspan="1">&GET;</td>
<td colspan="2"
>/<parameter>account</parameter>/<parameter>container</parameter></td>
<td colspan="3">Lists objects.</td>
</tr>
<tr>
<td colspan="1">&PUT;</td>
<td colspan="2"
>/<parameter>account</parameter>/<parameter>container</parameter></td>
<td colspan="3">Creates a container.</td>
</tr>
<tr>
<td colspan="1">&DELETE;</td>
<td colspan="2"
>/<parameter>account</parameter>/<parameter>container</parameter></td>
<td colspan="3">Deletes a container.</td>
</tr>
<tr>
<td colspan="1">&HEAD;</td>
<td colspan="2"
>/<parameter>account</parameter>/<parameter>container</parameter></td>
<td colspan="3">Gets container metadata.</td>
</tr>
</tbody>
</informaltable>
<para>All operations follow this format:</para>
<example>
<title>Storage Container Services HTTP Request</title>
<literallayout class="monospaced">METHOD /v1/&lt;account>/&lt;container> HTTP/1.1 </literallayout>
</example>
<section xml:id="list-objects">
<title>List Objects</title>
<para>&GET; operations against a storage container name are
performed to retrieve a list of objects stored in the
container. Additionally, there are a number of optional
query parameters that can be used to refine the list
results.</para>
<para>A request with no query parameters will return the full
list of object names stored in the container, up to 10,000
names. Optionally specifying the query parameters will
filter the full list and return a subset of
objects.</para>
<variablelist>
<title>Query Parameters</title>
<varlistentry>
<term><code>limit</code></term>
<listitem>
<para>For an integer value <inlineequation>
<mathphrase><emphasis>n</emphasis></mathphrase>
</inlineequation>, limits the number of
results to at most <inlineequation>
<mathphrase><emphasis>n</emphasis></mathphrase>
</inlineequation> values.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><code>marker</code></term>
<listitem>
<para>Given a string value <inlineequation>
<mathphrase><emphasis>x</emphasis></mathphrase>
</inlineequation>, return object names greater
in value than the specified marker.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><code>end_marker</code></term>
<listitem>
<para>Given a string value <inlineequation>
<mathphrase><emphasis>x</emphasis></mathphrase>
</inlineequation>, return object names less in
value than the specified marker.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><code>prefix</code></term>
<listitem>
<para>For a string value <inlineequation>
<mathphrase><emphasis>x</emphasis></mathphrase>
</inlineequation>, causes the results to be
limited to object names beginning with the
substring <inlineequation>
<mathphrase><emphasis>x</emphasis></mathphrase>
</inlineequation>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><code>format</code></term>
<listitem>
<para>Specify either <code>json</code> or
<code>xml</code> to return the respective
serialized response.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><code>delimiter</code></term>
<listitem>
<para>For a character <inlineequation>
<mathphrase><emphasis>c</emphasis></mathphrase>
</inlineequation>, return all the object names
nested in the container (without the need for
the directory marker objects).</para>
</listitem>
</varlistentry>
<varlistentry>
<term><code>path</code></term>
<listitem>
<para>For a string value<inlineequation>
<mathphrase><emphasis>x</emphasis></mathphrase>
</inlineequation>, return the object names
nested in the pseudo path. Equivalent to
setting delimiter to '/' and prefix to the
path with a '/' on the end.</para>
</listitem>
</varlistentry>
</variablelist>
<example>
<title>List Objects HTTP Request</title>
<literallayout class="monospaced"><xi:include href="samples/object-list-req.txt" parse="text"/></literallayout>
</example>
<para>A list of objects is returned in the response body, one
object name per line. A 204 (No Content) HTTP return code
will be passed back if the container is empty. If the
container does not exist, a 404 code will return. If an
incorrect account is specified, the HTTP return code will
be 404 (Not Found).</para>
<example>
<title>List Objects HTTP Response</title>
<literallayout class="monospaced"><xi:include href="samples/object-list-resp.txt" parse="text"/></literallayout>
</example>
<section xml:id="serialized-list-output">
<title>Serialized List Output</title>
<para>If a <code>format=xml</code> or
<code>format=json</code> argument is appended to
the storage account URL, the service will serve
extended object information serialized in the chosen
format. Other than the <code>?format=xml|json</code>
parameter, it will return the same status/errors
codes. The sample responses below are formatted for
readability.</para>
<example>
<title>Get Objects Details HTTP and JSON
Request</title>
<literallayout class="monospaced"><xi:include href="samples/objects-get-details-http-json-req.txt" parse="text"/></literallayout>
</example>
<example>
<title>Get Objects Details HTTP and JSON Response </title>
<literallayout class="monospaced"><xi:include href="samples/objects-get-details-http-json-resp.txt" parse="text"/></literallayout>
<programlisting language="json"><xi:include href="samples/objects-get-details-resp.json" parse="text"/></programlisting>
</example>
<example>
<title>Objects Details Request: XML</title>
<literallayout class="monospaced"><xi:include href="samples/objects-get-details-http-xml-req.txt" parse="text"/></literallayout>
</example>
<example>
<title>Objects Details Request: XML </title>
<literallayout class="monospaced"><xi:include href="samples/objects-get-details-http-xml-resp.txt" parse="text"/></literallayout>
<programlisting language="xml"><xi:include href="samples/objects-get-details-resp.xml" parse="text"/></programlisting>
</example>
</section>
<section xml:id="list-large-number-of-objects">
<title>Controlling a Large List of Objects</title>
<para>The system returns a maximum of 10,000 object names
per request. To retrieve subsequent object names,
another request must be made with the 'marker'
parameter. The marker indicates where the last list
left off and the system returns object names greater
than this marker, up to 10,000 again. Note that the
marker value should be URL encoded prior to sending
the HTTP request.</para>
<para>If 10,000 is larger than desired, a 'limit'
parameter may be given.</para>
<para>If the number of object names returned equals the
limit given (or 10,000 if no limit is given), it can
be assumed there are more object names to be listed.
If the container name list is exactly divisible by the
limit, the last request has no content.</para>
<example>
<title>List Large Number of Objects</title>
<para>For an example, let's use a listing of five
object names:</para>
<literallayout class="monospaced">gala
grannysmith
honeycrisp
jonagold
reddelicious</literallayout>
<para>We'll use a limit of two to show how things
work:</para>
<literallayout class="monospaced"><xi:include href="samples/objects-list-req.txt" parse="text"/></literallayout>
<para>Because we received two items back, we can
assume there are more object names to list. So, we
make another request with a marker of the last
item returned:</para>
<literallayout class="monospaced"><xi:include href="samples/objects-list-marker-req.txt" parse="text"/></literallayout>
<para>Again we have two items returned; there might be
more:</para>
<literallayout class="monospaced"><xi:include href="samples/objects-list-marker2-req.txt" parse="text"/></literallayout>
<para>Now we received less than the limit number of
object names, indicating that we have the complete
list.</para>
<para>By using <code>end_marker</code> we can limit
the result set to object names less than the given
value. </para>
<literallayout class="monospaced"><xi:include href="samples/objects-list-end-marker-req.txt" parse="text"/></literallayout>
</example>
</section>
<section xml:id="pseudo-hierarchical-folders-directories">
<title>Pseudo-Hierarchical Folders and Directories</title>
<!-- reworked this section / as path and its elements / are not supported - dsh - 02-16-12 -->
<para>Although you cannot nest directories in OpenStack
Object Storage, you can simulate a hierarchical
structure within a single container by adding forward
slash characters (<literal>/</literal>) in the object
name. To navigate the pseudo-directory structure, you
may use the <code>delimiter</code> query parameter.
See the below examples for an illustration.</para>
<note>
<para>In the example below, the objects reside in a
container called <code>backups</code>. Within that
container, the objects are organized in a
pseudo-directory called <code>photos</code>. Keep
in mind that the container name is not displayed
in the example, but that it is a part of the
object URLs. For instance, the URL of the picture
<code>me.jpg</code> is
<uri>https://storage.swiftdrive.com/v1/CF_xer7_343/backups/photos/me.jpg</uri>.
</para>
</note>
<example>
<title>List Pseudo-Hierarchical Folders/Directories
Request</title>
<para>To display a list of all the objects in the
storage container, use &GET; without a
<code>delimiter</code> or <code>prefix</code>. </para>
<literallayout class="monospaced">GET /v1/AccountString/backups</literallayout>
<para>The system returns status code 200 (OK) and the
requested list of the objects. </para>
<literallayout class="monospaced">photos/animals/cats/persian.jpg
photos/animals/cats/siamese.jpg
photos/animals/dogs/corgi.jpg
photos/animals/dogs/poodle.jpg
photos/animals/dogs/terrier.jpg
photos/me.jpg
photos/plants/fern.jpg
photos/plants/rose.jpg</literallayout>
<para>
<!-- The JIRA ticket / doc-97 subsumed / to this location - dsh - 02-03-12 -->Use
the delimiter parameter to limit the displayed
results. Any character may be used as a delimiter.
However, to use <code>delimiter</code> with
pseudo-directories, use the parameter slash
(<literal>/</literal>). </para>
<literallayout class="monospaced">GET /v1/AccountString/backups?delimiter=/</literallayout>
<para>The system returns status code 200 (OK) and the
requested matching objects. Because we use the
slash, only the pseudo-directory
<code>photos/</code> displays. Keep in mind
that the returned values from a slash
<code>delimiter</code> query are not real
objects. They have a content-type of
application/directory and are in a subdir section
of json and xml results. </para>
<literallayout class="monospaced">photos/</literallayout>
<para>Use the <code>prefix</code> parameter with the
<code>delimiter</code> parameter to view the
objects inside a pseudo-directory, including
further nested pseudo-directories. </para>
<literallayout class="monospaced">GET /v1/AccountString/backups?prefix=photos/&#38;delimiter=/</literallayout>
<para>The system returns status code 200 (OK) and the
objects and pseudo-directories within the top
level pseudo-directory. </para>
<literallayout class="monospaced">photos/animals/
photos/me.jpg
photos/plants/ </literallayout>
<para>There is no limit to the amount of nested
pseudo-directories you can create. In order to
navigate through them, use a longer
<code>prefix</code> parameter coupled with the
<code>delimiter</code> parameter. In the
sample output below, there is a pseudo-directory
called <code>dogs</code> within the
pseudo-directory <code>animals</code>. In order to
navigate directly to the files contained within
<code>dogs</code>, enter the below command. </para>
<literallayout class="monospaced">GET /v1/AccountString/backups?prefix=photos/animals/dogs/&#38;delimiter=/ </literallayout>
<para>The system returns status code 200 (OK) and the
objects and pseudo-directories within the nested
pseudo-directory. </para>
<literallayout class="monospaced">photos/animals/dogs/corgi.jpg
photos/animals/dogs/poodle.jpg
photos/animals/dogs/terrier.jpg</literallayout>
</example>
</section>
</section>
<section xml:id="create-container">
<title>Create Container</title>
<para>&PUT; operations against a storage container are used to
create that container.</para>
<para>Containers are storage compartments for your data. The
URL encoded name must be less than 256 bytes and cannot
contain a forward slash '/' character.</para>
<para>Containers can be assigned custom metadata by including
additional HTTP headers on the &PUT; request. The custom
metadata is assigned to a container via HTTP headers
identified with the <code>X-Container-Meta-</code> prefix. </para>
<example>
<title>Create Container HTTP Request </title>
<literallayout class="monospaced"><xi:include href="samples/container-create-req.txt" parse="text"/></literallayout>
</example>
<para>No content is returned. A status code of 201 (Created)
indicates that the container was created as requested.
Container &PUT; requests are idempotent and a code of 202
(Accepted) is returned when the container already existed.
If you request a &PUT; to a container with an
<code>X-Container-Meta-</code> prefix in the header,
your &GET;/&HEAD; request responses carry the metadata
prefix from the container in subsequent requests.</para>
<example>
<title>Create Container HTTP Response</title>
<literallayout class="monospaced"><xi:include href="samples/container-create-resp.txt" parse="text"/></literallayout>
</example>
<para>Using custom container metadata, you can create
information in the header to effectively "tag" a container
with metadata. The container metadata restrictions are the
same as object metadata: you can have 4096 bytes maximum
overall metadata, 90 distinct metadata items at the most.
Each may have a 128 character name length with a 256 max
value length each. Any valid UTF-8 http header value is
allowed for metadata, however we recommend that you
URL-encode any non-ASCII values using a "%" symbol,
followed by the two-digit hexadecimal representation of
the ISO-Latin code for the character.</para>
<example>
<title>Container Create Container with Metadata HTTP Request</title>
<literallayout class="monospaced"><xi:include href="samples/container-create-metadata-req.txt" parse="text"/></literallayout>
</example>
<para>No content is returned. A status code of 201 (Created)
indicates that the container was created as requested.
Container &PUT; requests are idempotent and a code of 202
(Accepted) is returned if the container existed prior to
the request. If you request a &PUT; to a container with an
<code>X-Container-Meta-</code> prefix in the header,
your &GET;/&HEAD; request responses carry the metadata
prefix from the container in subsequent requests.</para>
<example>
<title>Create Container with Metadata HTTP Response</title>
<literallayout class="monospaced"><xi:include href="samples/container-create-metadata-resp.txt" parse="text"/></literallayout>
</example>
</section>
<section xml:id="delete-container">
<title>Delete Container</title>
<para>&DELETE; operations against a storage container
permanently remove it. The container must be empty before
it can be deleted. </para>
<para>A &HEAD; request against the container can be used to
determine if it contains any objects.</para>
<example>
<title>Delete Container HTTP Request</title>
<literallayout class="monospaced"><xi:include href="samples/container-delete-req.txt" parse="text"/></literallayout>
</example>
<para>No content is returned. A status code of 204 (No
Content) indicates success, 404 (Not Found) is returned if
the requested container was not found, and a 409
(Conflict) if the container is not empty. No response body
is generated.</para>
<example>
<title>Delete Container HTTP Response</title>
<literallayout class="monospaced"><xi:include href="samples/container-delete-resp.txt" parse="text"/></literallayout>
</example>
</section>
<section xml:id="retrieve-container-metadata">
<title>Get Container Metadata</title>
<para>&HEAD; operations against a storage container are used
to determine the number of objects, and the total bytes of
all objects stored in the container. Since the storage
system is designed to store large amounts of data, care
should be taken when representing the total bytes response
as an integer; when possible, convert it to a 64-bit
unsigned integer if your platform supports that primitive
type.</para>
<example>
<title>Get Container Metadata HTTP Request</title>
<literallayout class="monospaced"><xi:include href="samples/container-get-metadata-req.txt" parse="text"/></literallayout>
</example>
<para>The HTTP return code will be 204 (No Content) if the
container exists, and 404 (Not Found) if it does not. The
object count and utilization are returned in the
<code>X-Container-Object-Count</code> and
<code>X-Container-Bytes-Used</code> headers
respectively.</para>
<example>
<title>Get Container Metadata HTTP Response</title>
<literallayout class="monospaced"><xi:include href="samples/container-get-metadata-resp.txt" parse="text"/></literallayout>
</example>
</section>
<section xml:id="Update_Container_Metadata-d1e1900">
<title>Create or Update Container Metadata</title>
<para>You may create any custom or arbitrary metadata headers
as you find useful. They must, however, take the format
<code>X-Container-Meta-</code>. </para>
<para>To create or update the arbitrary container metadata,
use the &POST; query. Subsequent requests of the same
key/value pair overwrites the previous value. </para>
<example>
<title>Update Container Metadata HTTP Request</title>
<literallayout class="monospaced"><xi:include href="samples/container-update-metadata-req.txt" parse="text"/></literallayout>
</example>
<para>No response body is returned. A status code of 204 (No
Content) indicates success; status 404 (Not Found) is
returned when the requested container does not exist. </para>
<example>
<title>Update Container Metadata HTTP Response</title>
<literallayout class="monospaced"><xi:include href="samples/container-update-metadata-resp.txt" parse="text"/></literallayout>
</example>
<para>To confirm your metadata changes, perform a &HEAD;
request on the container. Do not send the metadata in your
&HEAD; request.</para>
<example>
<title>View Container Metadata HTTP Request</title>
<literallayout class="monospaced"><xi:include href="samples/container-view-metadata-req.txt" parse="text"/></literallayout>
</example>
<example>
<title>View Container Metadata HTTP Response</title>
<literallayout class="monospaced"><xi:include href="samples/container-view-metadata-resp.txt" parse="text"/></literallayout>
</example>
<!-- Note: using POST with null value should delete a metadata header, but
this method is not functional with all tools, so we are leaving it out for now.
A future patch may come where using "-" (dash) for the value will delete it. dsh - 2012-0309 -->
</section>
<section xml:id="delete-container-metadata">
<title>Delete Container Metadata</title>
<para>To delete a metadata header send an empty value for that
particular header, such as
<code>X-Container-Meta-Book:</code>. </para>
<para>If the tool you're using to communicate with Object
Storage doesn't support sending empty headers (older
versions of curl) send the header
"X-Remove-Container-Meta-<replaceable>name</replaceable>:
<replaceable>arbitrary value</replaceable>". For
example, send a header like
<code>X-Remove-Container-Meta-Book: x</code>. The
<emphasis>value</emphasis> (x in this example) is
ignored.</para>
<example>
<title>Delete Container Metadata HTTP Request</title>
<literallayout class="monospaced"><xi:include href="samples/container-delete-metadata-req.txt" parse="text"/></literallayout>
<para>No response body is returned. A status code of 204
(No Content) indicates success. </para>
</example>
</section>
</section>

View File

@@ -0,0 +1,701 @@
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE section [
<!-- Some useful entities borrowed from HTML -->
<!ENTITY ndash "&#x2013;">
<!ENTITY mdash "&#x2014;">
<!ENTITY hellip "&#x2026;">
<!-- Useful for describing APIs -->
<!ENTITY COPY '<command xmlns="http://docbook.org/ns/docbook">COPY</command>'>
<!ENTITY GET '<command xmlns="http://docbook.org/ns/docbook">GET</command>'>
<!ENTITY HEAD '<command xmlns="http://docbook.org/ns/docbook">HEAD</command>'>
<!ENTITY PUT '<command xmlns="http://docbook.org/ns/docbook">PUT</command>'>
<!ENTITY POST '<command xmlns="http://docbook.org/ns/docbook">POST</command>'>
<!ENTITY DELETE '<command xmlns="http://docbook.org/ns/docbook">DELETE</command>'>
<!ENTITY CHECK '<inlinemediaobject xmlns="http://docbook.org/ns/docbook">
<imageobject>
<imagedata fileref="img/Check_mark_23x20_02.svg"
format="SVG" scale="60"/>
</imageobject>
</inlinemediaobject>'>
<!ENTITY ARROW '<inlinemediaobject xmlns="http://docbook.org/ns/docbook">
<imageobject>
<imagedata fileref="img/Arrow_east.svg"
format="SVG" scale="60"/>
</imageobject>
</inlinemediaobject>'>
]>
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0"
xml:id="storage-object-services">
<title>Storage Object Services</title>
<para>An object represents the data and any metadata for the files
stored in the system. Through the ReST interface, metadata for
an object can be included by adding custom HTTP headers to the
request and the data payload as the request body. Objects
cannot exceed 5GB and must have names that do not exceed 1024
bytes after URL encoding. However, objects larger than 5GB can
be segmented and then concatenated together so that you can
upload 5 GB segments and download a single concatenated
object. You can work with the segments and manifests directly
with HTTP requests.</para>
<informaltable rules="all">
<thead>
<tr>
<td colspan="1">Verb</td>
<td colspan="2">URI</td>
<td colspan="3">Description</td>
</tr>
</thead>
<tbody>
<tr>
<td colspan="1">&GET;</td>
<td colspan="2"
>/<parameter>account</parameter>/<parameter>container</parameter>/<parameter>object</parameter></td>
<td colspan="3">Gets object details.</td>
</tr>
<tr>
<td colspan="1">&PUT;</td>
<td colspan="2"
>/<parameter>account</parameter>/<parameter>container</parameter>/<parameter>object</parameter></td>
<td colspan="3">Creates or updates object.</td>
</tr>
<tr>
<td colspan="1">&PUT;</td>
<td colspan="2"
>/<parameter>account</parameter>/<parameter>container</parameter>/<parameter>object</parameter></td>
<td colspan="3">Chunked transfer encoding</td>
</tr>
<tr>
<td colspan="1">&DELETE;</td>
<td colspan="2"
>/<parameter>account</parameter>/<parameter>container</parameter>/<parameter>object</parameter></td>
<td colspan="3">Deletes container.</td>
</tr>
<tr>
<td colspan="1">&HEAD;</td>
<td colspan="2"
>/<parameter>account</parameter>/<parameter>container</parameter>/<parameter>object</parameter></td>
<td colspan="3">Gets object metadata.</td>
</tr>
<tr>
<td colspan="1">&POST;</td>
<td colspan="2"
>/<parameter>account</parameter>/<parameter>container</parameter>/<parameter>object</parameter></td>
<td colspan="3">Updates object metadata.</td>
</tr>
</tbody>
</informaltable>
<section xml:id="retrieve-object">
<title>Get Object Details</title>
<para>&GET; operations against an object are used to retrieve
the object's data.</para>
<para>Note that you can perform conditional &GET; requests by
using certain HTTP headers as documented in RFC 2616.
OpenStack Object Storage supports the following
headers:</para>
<para>RFC 2616: <link
xlink:href="http://www.ietf.org/rfc/rfc2616.txt"
>http://www.ietf.org/rfc/rfc2616.txt</link>
</para>
<itemizedlist>
<listitem>
<para>If-Match</para>
</listitem>
<listitem>
<para>If-None-Match</para>
</listitem>
<listitem>
<para>If-Modified-Since</para>
</listitem>
<listitem>
<para>If-Unmodified-Since</para>
</listitem>
</itemizedlist>
<para>It is also possible to fetch a portion of data using the
HTTP <code>Range</code> header. At this time, OpenStack
Object Storage does not support the full specification for
<code>Range</code> but basic support is provided.
OpenStack Object Storage only allows a single range that
includes OFFSET and/or LENGTH. We support a sub-set of
<code>Range</code> and do not adhere to the full
RFC-2616 specification. We support specifying
OFFSET-LENGTH where either OFFSET or LENGTH can be
optional (not both at the same time). The following are
supported forms of the header:</para>
<itemizedlist>
<listitem>
<para><code>Range: bytes=-5</code> - last five bytes
of the object</para>
</listitem>
<listitem>
<para><code>Range: bytes=10-15</code> - the five bytes
after a 10-byte offset</para>
</listitem>
<listitem>
<para><code>Range: bytes=32-</code> - all data after
the first 32 bytes of the object</para>
</listitem>
</itemizedlist>
<example>
<title>Get Object Details HTTP Request</title>
<literallayout class="monospaced"><xi:include href="samples/object-get-req.txt" parse="text"/></literallayout>
</example>
<para>The object's data is returned in the response body.
Object metadata is returned as HTTP headers. A status of
200 (Ok) indicates success; status 404 (Not Found) is
returned if no such object exists.</para>
<example>
<title>Get Object Details HTTP Response</title>
<literallayout class="monospaced"><xi:include href="samples/object-get-resp.txt" parse="text"/></literallayout>
<literallayout class="monospaced">[ ... ]</literallayout>
</example>
</section>
<section xml:id="create-update-object">
<title>Create or Update Object</title>
<para>&PUT; operations are used to write, or overwrite, an
object's content and metadata. </para>
<para>You can ensure end-to-end data integrity by including an
MD5 checksum of your object's data in the ETag header. You
are not required to include the ETag header, but it is
recommended to ensure that the storage system successfully
stored your object's content.</para>
<para>You can cause an object to expire after a certain date
by using the <code>X-Delete-At</code> or
<code>X-Delete-After</code> headers during an object
&PUT; operation. When Cloud Files detects one of these
headers, the system automatically stops serving that
object at the specified time and shortly after the
expiration date, it removes the object from the storage
system. </para>
<para>The HTTP response will include the MD5 checksum of the
data written to the storage system. If you do not send the
ETag in the request, you should compare the value returned
with your content's MD5 locally to perform the end-to-end
data validation on the client side. For segmented objects,
the ETag is the MD5 sum of the concatenated string of
ETags for each of the segments in the manifest, which only
offers change detection but not direct comparison.</para>
<para>Objects can be assigned custom metadata by including
additional HTTP headers on the &PUT; request.</para>
<para>The object can be created with custom metadata via HTTP
headers identified with the <code>X-Object-Meta-</code>
prefix.</para>
<example>
<title>Create or Update Object HTTP Request</title>
<literallayout class="monospaced"><xi:include href="samples/object-create-req.txt" parse="text"/></literallayout>
<literallayout class="monospaced">[ ... ]</literallayout>
</example>
<para>No response body is returned. A status code of 201
(Created) indicates a successful write; status 411 (Length
Required) denotes a missing <code>Content-Length</code> or
<code>Content-Type</code> 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.</para>
<example>
<title>Create or Update Object HTTP Response</title>
<literallayout class="monospaced"><xi:include href="samples/object-create-resp.txt" parse="text"/></literallayout>
</example>
<section xml:id="large-object-creation">
<title>Create Large Objects</title>
<para>Objects that are larger than 5GB must be segmented,
prior to upload. You then upload the segments like you
would any other object and create a manifest object
telling OpenStack Object Storage how to find the
segments of 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.</para>
<para>To ensure the download works correctly, you
must upload all the object segments to the same
container, ensure each object name has a common prefix
where their names sort in the order they should be
concatenated. You also create and upload a manifest
file. The manifest file is simply a zero-byte file
with the extra X-Object-Manifest:
&lt;container&gt;/&lt;prefix&gt; header, where
&lt;container&gt; is the container the object segments
are in and &lt;prefix&gt; is the common prefix for all
the segments. </para>
<para>It is best to upload all the segments first and then
create or update the manifest. With this method, the
full object will not be available for downloading
until the upload is complete. Also, you can upload a
new set of segments to a second location and then
update the manifest to point to this new location.
During the upload of the new segments, the original
manifest will still be available to download the first
set of segments.</para>
<example>
<title>Upload Segment of Large Object HTTP Request</title>
<literallayout class="monospaced"><xi:include href="samples/large-object-upload-segment-req.txt" parse="text"/></literallayout>
</example>
<example>
<title>Upload Segment of Large Object
HTTP Response</title>
<literallayout class="monospaced">s</literallayout>
</example>
<para>No response body is returned. A status code of 201
(Created) indicates a successful write; status 411
(Length Required) denotes a missing
<code>Content-Length</code> or
<code>Content-Type</code> 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.</para>
<para>You can continue uploading segments like this
example shows, prior to uploading the manifest.</para>
<example>
<title>Upload Next Segment of Large Object HTTP Request</title>
<literallayout class="monospaced"><xi:include href="samples/large-object-upload-next-segment-req.txt" parse="text"/></literallayout>
</example>
<example>
<title>Upload Next Segment of Large Object
HTTP Response</title>
<literallayout class="monospaced">w</literallayout>
</example>
<para>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 will cause the concatenated object to be
that much larger but you do not need to recreate the
manifest file for subsequent additional
segments.</para>
<example>
<title>Upload Manifest HTTP Request</title>
<literallayout class="monospaced"><xi:include href="samples/upload-manifest-req.txt" parse="text"/></literallayout>
</example>
<example>
<title>Upload Manifest HTTP Response</title>
<literallayout class="monospaced"><xi:include href="samples/upload-manifest-resp.txt" parse="text"/></literallayout>
</example>
<para>The response's Content-Type for a &GET; or &HEAD; on
the manifest will be 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.</para>
</section>
<section xml:id="chunked-transfer-encoding">
<title>Chunked Transfer Encoding</title>
<para>Users can upload data without needing to know in
advance the amount of data to be uploaded. Users can
do this by specifying an HTTP header of
<code>Transfer-Encoding: chunked</code> and not
using a <code>Content-Length</code> header. A good use
of this feature would be doing a DB dump, piping the
output through gzip, then piping the data directly
into OpenStack Object Storage without having to buffer
the data to disk to compute the file size. If users
attempt to upload more than 5GB with this method, the
server will close the TCP/IP connection after 5GB and
purge the customer data from the system. Users must
take responsibility for ensuring the data they
transfer will be less than 5GB or for splitting it
into 5GB chunks, each in its own storage object. If
you have files that are larger than 5GB and still want
to use Object Storage, you can segment them prior to
upload, upload them to the same container, and then
use a manifest file to allow downloading of a
concatenated object containing all the segmented
objects, concatenated as a single object. </para>
<example>
<title>Upload Unspecified Quantity of Content
HTTP Request</title>
<literallayout class="monospaced"><xi:include href="samples/chunked-transfer-encoding-req.txt" parse="text"/></literallayout>
</example>
<example>
<title>Upload Unspecified Quantity of Content
HTTP Response</title>
<literallayout class="monospaced"><xi:include href="samples/chunked-transfer-encoding-resp.txt" parse="text"/></literallayout>
</example>
</section>
</section>
<section xml:id="assigning-cors-headers-to-requests">
<title>Assigning CORS Headers to Requests</title>
<para>CORS is a specification that stands for Cross-Origin
Resource Sharing. It defines how browsers and servers
communicate across origins using HTTP headers, such as
those assigned by Cloud Files API requests. These headers
are supported with the Cloud Files API. You can read more
about the definition of the Access-Control- response
headers and Origin response header at <link
xlink:href="http://www.w3.org/TR/access-control/"
>www.w3.org/TR/access-control/</link>.<itemizedlist>
<listitem>
<para>Access-Control-Allow-Credentials</para>
</listitem>
<listitem>
<para>Access-Control-Allow-Methods</para>
</listitem>
<listitem>
<para>Access-Control-Allow-Origin</para>
</listitem>
<listitem>
<para>Access-Control-Expose-Headers</para>
</listitem>
<listitem>
<para>Access-Control-Max-Age</para>
</listitem>
<listitem>
<para>Access-Control-Request-Headers</para>
</listitem>
<listitem>
<para>Access-Control-Request-Method</para>
</listitem>
<listitem>
<para>Origin</para>
</listitem>
</itemizedlist></para>
<para>You can assign these headers to objects only. </para>
<example>
<title>Assign CORS Header HTTP Request</title>
<para>In the example, the origin header is assigned that
indicates where the file came from. This allows you to
provide security that requests to your Cloud Files
repository are indeed from the correct
origination:</para>
<literallayout class="monospaced"><xi:include href="samples/object-assign-cors-header-req.txt" parse="text"/></literallayout>
</example>
</section>
<section
xml:id="enabling-file-compression-with-content-encoding-header">
<title>Enabling File Compression with the Content-Encoding
Header</title>
<para>The Content-Encoding header allows a file to be
compressed without losing the identity of the underlying
media type of the file, for example, a video.</para>
<example>
<title>Content-Encoding Header HTTP Request</title>
<para>In the example, the content-encoding header is
assigned with an attachment type that indicates how
the file should be downloaded:</para>
<literallayout class="monospaced"><xi:include href="samples/content-encoding-header-req.txt" parse="text"/></literallayout>
</example>
</section>
<section
xml:id="enabling-browser-bypass-with-content-disposition-header">
<title>Enabling Browser Bypass with the Content-Disposition
Header</title>
<para>When an object is assigned the Content-Disposition
header you can override a browser's default behavior for a
file so that the download program saves the file rather
than displaying it using default browser settings.</para>
<example>
<title>Content-Disposition Header HTTP Request</title>
<para>In the example, the content-encoding header is
assigned with an attachment type that indicates how
the file should be downloaded.</para>
<literallayout class="monospaced"><xi:include href="samples/content-disposition-header-req.txt" parse="text"/></literallayout>
</example>
</section>
<section xml:id="Expiring_Objects-e1e3228">
<title>Expiring Objects with the X-Delete-After and
X-Delete-At Headers</title>
<para>When an object is assigned either an
<code>X-Delete-After</code> or
<code>X-Delete-At</code> header when doing a &PUT; or
&POST; on the object, it is scheduled for deletion. This
feature is helpful for objects you do not want to
permanently store, such as log files, recurring full
backups of a dataset, or documents or images you know will
be outdated at a future time.</para>
<para>The <code>X-Delete-At</code> header requires a Unix
Epoch timestamp, in integer form; for example: 1348691905
represents Wed, 26 Sep 2012 20:38:25 GMT.
<!-- Exchanged POSIX in / favor of Epoch for the / sake of clarity dsh 02-06-12 -->By
setting the header to a specific Epoch time, you indicate
when you want the object to expire, not be served, and be
deleted completely from the storage system. </para>
<para>The <code>X-Delete-After</code> header takes an integer
number of seconds and calculates the amount of time from
now that you want the object to be deleted. The proxy
server that receives the request converts this header into
an <code>X-Delete-At</code> header and calculates the
deletion time using its current time plus the value given
in seconds.</para>
<para>For existing objects that you want to assign expiration
headers to, use the &POST; operation.</para>
<example>
<title>Delete Object at HTTP Request</title>
<para>In the example, the <code>X-Delete-At</code> header
is assigned with a Unix Epoch timestamp in integer
form for Mon, 11 Jun 2012 15:38:25 GMT. Use <link
xlink:href="http://www.epochconverter.com/"
>http://www.epochconverter.com/</link> for example
timestamps and a batch converter.</para>
<literallayout class="monospaced"><xi:include href="samples/object-delete-at-req.txt" parse="text"/></literallayout>
</example>
<example>
<title>Delete Object after HTTP Request</title>
<para><!-- Reworded this here / paragraph to make more sense / and match what I see dsh 02-06-12 -->In
this example, the <code>X-Delete-After</code> header
is assigned a value in seconds, equivalent to 10 days.
After this time, the object expires.</para>
<!-- Removed, "The system then converts the time necessary for an <code>X-Delete-At</code> header operation." Doesn't seem to match dsh 02-06-12-->
<literallayout class="monospaced"><xi:include href="samples/object-delete-after-req.txt" parse="text"/></literallayout>
</example>
</section>
<section xml:id="Object_Versioning-e1e3230">
<!-- begin 4.3.2.7 -->
<title>Object Versioning</title>
<para>Object Versioning allows you to store multiple versions
of your content to recover from unintended overwrites. It
provides an easy method to implement version control which
can be used on any type of content. It is strongly
recommended that you put non-current objects in a
container apart from where the current versions exist.
Once you enable Object Versioning on a container (such as
a "current version" container), PUTs to existing objects
in that container copy the prior object to a separate
"non-current version" container. Each of the non-current
versions of an object has a time stamp appended to it, so
you know when it was created. </para>
<para>To enable Object Versioning, your cloud provider has to
set <code>allow_versions</code> to <code>TRUE</code> in
their container config. Then, create a container where
your non-current versions will be written. Next, set the
metadata <code>X-Versions-Location</code> header on the
container that holds the current versions of your objects.
Set the metadata header to point to the new non-current
version container you created. This is where your
non-current versions will be stored. Once this is done,
each object in your current-version container will have
Object Versioning enabled; changes to the objects
automatically create non-current versions in the separate
container. </para>
<para>Nothing is written to the non-current version container
when you initially &PUT; an object into the
current-version container. Only when you make edits to the
objects via &PUT; will you create non-current versions.
These non-current versions are labeled according to the
schema below. </para>
<para>
<emphasis>Naming Schema:</emphasis> Non-current versions
are assigned the name
&lt;length&gt;&lt;object_name&gt;/&lt;timestamp&gt;, where
length is the 3-character zero-padded hexadecimal
character length of the &lt;object_name&gt; and
&lt;timestamp&gt; is when the it was initially created as
a current version. </para>
<para>Any return status in the 2xx range, such as 202
(Accepted), notes success. Status codes in the 4xx or 5xx
range note failure. You should retry your request if you
receive an error. Please note, however, that if you have
specified a container that does not exist as your
non-current version container, a status of 412
(Precondition Failed) returns when you edit the versioned
object. If you receive this error, check that the
container exists. </para>
<para>A &GET; to a versioned object returns the current
version of the object without having to do any request
redirects or metadata lookups. </para>
<para>A &POST; to a versioned object only updates the object's
metadata; it does not create a new version of the object.
In other words, new versions are only created when the
content of the object changes. </para>
<para>A &DELETE; to a versioned object removes the current
version of the object and replaces it with the next-most
current version, moving it from the non-current container
to the current. 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 total versions of it,
you must &DELETE; it five times. </para>
<note>
<para> A large-object manifest file cannot be versioned,
but it may point to versioned segments. </para>
</note>
<para> To turn off Object Versioning on your current version
container, remove its <code>X-Versions-Location</code>
metadata by sending an empty key value. </para>
<example>
<title>Object Versioning with cURL</title>
<para>Make sure a version-storing container exists,
creating it if necessary (this example names it
"versions"). Then create a container with the
<code>X-Versions-Location</code> header. In this
example, this container is named "current". You can
also add the <code>X-Versions-Location</code> header
to an existing container. In this example, the name of
the container is “versions”; the location for the
current version is the container "current". </para>
<para>Create a container named versions.</para>
<literallayout class="monospaced"> curl -i -XPUT -H "X-Auth-Token: &lt;token&gt;" http://&lt;storage_url&gt;/versions</literallayout>
<para>Create a container named current with the
<code>X-Versions-Location</code> header that
references "versions".</para>
<literallayout class="monospaced">
curl -i -XPUT -H "X-Auth-Token: &lt;token&gt;" \
-H "X-Versions-Location: versions" http://&lt;storage_url&gt;/current
</literallayout>
<para>Create an object (the first version): </para>
<literallayout class="monospaced">
curl -i -XPUT --data-binary 1 -H "X-Auth-Token: &lt;token&gt;" \
http://&lt;storage_url&gt;/current/myobject
</literallayout>
<para>Now create a new version of that object: </para>
<literallayout class="monospaced">
curl -i -XPUT --data-binary 2 -H "X-Auth-Token: &lt;token&gt;" \
http://&lt;storage_url&gt;/current/myobject
</literallayout>
<para>See a listing of the older versions of the object: </para>
<literallayout class="monospaced">
curl -i -H "X-Auth-Token: &lt;token&gt;" \
http://&lt;storage_url&gt;/versions?prefix=008myobject/
</literallayout>
<para>Now delete the current version of the object and see
that the older version is gone: </para>
<literallayout class="monospaced">
curl -i -XDELETE -H "X-Auth-Token: &lt;token&gt;" \
http://&lt;storage_url&gt;/current/myobject
curl -i -H "X-Auth-Token: &lt;token&gt;" \
http://&lt;storage_url&gt;/versions?prefix=008myobject/
</literallayout>
</example>
</section>
<section xml:id="copy-object">
<title>Copy Object</title>
<para>Suppose you upload a file with the wrong object name or
content type, or you needed to move some objects to
another container. Without a server-side copy feature, you
would need to repeat uploading the same content and then
delete the existing object. With server-side object copy,
you can save the step of re-uploading the content and thus
also save the associated bandwidth charges, if any were to
apply. </para>
<para>There are two ways to copy an existing object to another
object in OpenStack Object Storage. One way is to do a
&PUT; to the new object (the target) location, but add the
<code>“X-Copy-From”</code> header to designate the
source of the data. The header value should be the
container and object name of the source object in the form
of “/container/object”. Also, the <code>X-Copy-From</code>
&PUT; requests require a Content-Length header, even if it
is zero (0).</para>
<example>
<title>Object Copy Method 1</title>
<literallayout class="monospaced"><xi:include href="samples/object-copy-1-req.txt" parse="text"/></literallayout>
</example>
<para>The second way to do an object copy is similar. Do a
&COPY; to the existing object, and include the
“Destination” header to specify the target of the copy.
The header value is the container and new object name in
the form of “/container/object”. </para>
<example>
<title>Object Copy Method 2</title>
<literallayout class="monospaced"><xi:include href="samples/object-copy-2-req.txt" parse="text"/></literallayout>
</example>
<para>With both of these methods, the destination container
must exist before attempting the copy.</para>
<para>If you wanted to move the object rather than copy it,
you need to send a &DELETE; request to the old object. A
move is simply a &COPY; + &DELETE;. All metadata is
preserved during the object copy. Note that you can set
metadata on the request to copy the object (either the
&PUT; or the &COPY;) and the metadata will overwrite any
conflicting keys on the target (new) object. One
interesting use case is to copy an object to itself and
set the content type to a new value. This is the only way
to change the content type of an existing object. </para>
</section>
<section xml:id="delete-object">
<title>Delete Object</title>
<para>&DELETE; operations on an object are used to permanently
remove an object from the storage system (metadata and
data).</para>
<para>Deleting an object is processed immediately at the time
of the request. Any subsequent &GET;, &HEAD;, &POST;, or
&DELETE; operations will return a 404 (Not Found) error. </para>
<para>Objects with the <code>X-Delete-At</code> or
<code>X-Delete-After</code> header assigned are
deleted within one day of the expiration time and the
object is not served immediately after the expiration
time. Refer to <link linkend="Expiring_Objects-e1e3228"
>Expiring Objects</link> for more details. </para>
<example>
<title>Object Delete HTTP Request</title>
<literallayout class="monospaced"><xi:include href="samples/object-delete-req.txt" parse="text"/></literallayout>
</example>
<para>No response body is returned. A status code of 204 (No
Content) indicates success; status code 404 (Not Found) is
returned when the object does not exist.</para>
<example>
<title>Object Delete HTTP Response</title>
<literallayout class="monospaced"><xi:include href="samples/object-delete-resp.txt" parse="text"/></literallayout>
</example>
</section>
<section xml:id="retrieve-object-metadata">
<title>Get Object Metadata</title>
<para>&HEAD; operations on an object are used to retrieve
object metadata and other standard HTTP headers.</para>
<para>The only required header to be sent in the request is
the authorization token.</para>
<example>
<title>Get Object Metadata HTTP Request</title>
<literallayout class="monospaced"><xi:include href="samples/object-metadata-req.txt" parse="text"/></literallayout>
</example>
<para>No response body is returned. Metadata is returned as
HTTP headers. A status code of 200 (OK) indicates success;
status 404 (Not Found) is returned when the object does
not exist. </para>
<para>The &HEAD; return code for the object
is different from that of the container. &HEAD; requests
do not return a message body in the response, so anything
in the 2xx response code range notes success. When a
&HEAD; query is run against the container, it queries the
container databases, and it does not retrieve the content
of them, thus the 204 (No Content) return code. However,
when a &HEAD; query is run against the object, it returns
an "OK" response because it can view the content. In other
words, the object &HEAD; query has a container length, but
the container &HEAD; query has zero content length. </para>
<example>
<title>Get Object Metadata HTTP Response</title>
<literallayout class="monospaced"><xi:include href="samples/object-metadata-resp.txt" parse="text"/></literallayout>
</example>
</section>
<section xml:id="update-object-metadata">
<title>Update Object Metadata</title>
<para>&POST; operations against an object name are used to set
and overwrite arbitrary key/value metadata or to assign
headers not already assigned such as
<code>X-Delete-At</code> or
<code>X-Delete-After</code> for expiring objects. You
cannot use the &POST; operation to change any of the
object's other headers such as <code>Content-Type</code>,
<code>ETag</code>, etc. It is not used to upload
storage objects (see &PUT;). Also refer to <link
linkend="copy-object">copying an object</link> when
you need to update metadata or other headers such as
Content-Type or CORS headers. </para>
<para>Key names must be prefixed with
<code>X-Object-Meta-</code>. A &POST; request will
delete all existing metadata added with a previous
&PUT;/&POST;.</para>
<example>
<title>Update Object Metadata HTTP Request</title>
<literallayout class="monospaced"><xi:include href="samples/object-update-metadata-req.txt" parse="text"/></literallayout>
</example>
<para>No response body is returned. A status code of 202
(Accepted) indicates success; status 404 (Not Found) is
returned if the requested object does not exist. </para>
<example>
<title>Update Object Metadata HTTP Response</title>
<literallayout class="monospaced"><xi:include href="samples/object-update-metadata-resp.txt" parse="text"/></literallayout>
</example>
</section>
</section>

View File

@@ -0,0 +1,305 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section [
<!-- Some useful entities borrowed from HTML -->
<!ENTITY ndash "&#x2013;">
<!ENTITY mdash "&#x2014;">
<!ENTITY hellip "&#x2026;">
<!-- Useful for describing APIs -->
<!ENTITY COPY '<command xmlns="http://docbook.org/ns/docbook">COPY</command>'>
<!ENTITY GET '<command xmlns="http://docbook.org/ns/docbook">GET</command>'>
<!ENTITY HEAD '<command xmlns="http://docbook.org/ns/docbook">HEAD</command>'>
<!ENTITY PUT '<command xmlns="http://docbook.org/ns/docbook">PUT</command>'>
<!ENTITY POST '<command xmlns="http://docbook.org/ns/docbook">POST</command>'>
<!ENTITY DELETE '<command xmlns="http://docbook.org/ns/docbook">DELETE</command>'>
<!ENTITY CHECK '<inlinemediaobject xmlns="http://docbook.org/ns/docbook">
<imageobject>
<imagedata fileref="img/Check_mark_23x20_02.svg"
format="SVG" scale="60"/>
</imageobject>
</inlinemediaobject>'>
<!ENTITY ARROW '<inlinemediaobject xmlns="http://docbook.org/ns/docbook">
<imageobject>
<imagedata fileref="img/Arrow_east.svg"
format="SVG" scale="60"/>
</imageobject>
</inlinemediaobject>'>
]>
<section xml:id="storage-account-services"
xmlns="http://docbook.org/ns/docbook"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0">
<title>Storage Account Services</title>
<para>Perform the following operations at the account level of the
URL:</para>
<informaltable rules="all">
<thead>
<tr>
<td colspan="1">Verb</td>
<td colspan="2">URI</td>
<td colspan="3">Description</td>
</tr>
</thead>
<tbody>
<tr>
<td colspan="1">&GET;</td>
<td colspan="2">/<parameter>account</parameter></td>
<td colspan="3">Lists containers.</td>
</tr>
<tr>
<td colspan="1">&HEAD;</td>
<td colspan="2">/<parameter>account</parameter></td>
<td colspan="3">Gets account metadata.</td>
</tr>
<tr>
<td colspan="1">&POST;</td>
<td colspan="2">/<parameter>account</parameter></td>
<td colspan="3">Creates or updates account metadata.</td>
</tr>
<tr>
<td colspan="1">&POST;</td>
<td colspan="2">/<parameter>account</parameter></td>
<td colspan="3">Deletes account metadata.</td>
</tr>
</tbody>
</informaltable>
<para>For example, the URL for the requests end with the OpenStack
Object Storage account string, as follows:</para>
<example>
<title>Storage Account Services HTTP Request</title>
<literallayout class="monospaced"><xi:include href="samples/object-api-general-req.txt" parse="text"/></literallayout>
</example>
<section xml:id="s_listcontainers">
<title>List Containers</title>
<para>&GET; operations against the <code>X-Storage-Url</code>
for an account are performed to retrieve a list of
existing storage containers ordered by name. The sort
order for the name is based on a <link
xlink:href="http://www.sqlite.org/datatype3.html#collation"
>binary comparison</link>, a single built-in collating
sequence that compares string data using SQLite's memcmp()
function, regardless of text encoding. The following list
describes the optional query parameters that are supported
with this request.</para>
<variablelist>
<title>Query Parameters</title>
<varlistentry>
<term><code>limit</code></term>
<listitem>
<para>For an integer value <inlineequation>
<mathphrase><emphasis>n</emphasis></mathphrase>
</inlineequation>, limits the number of
results to <inlineequation>
<mathphrase><emphasis>n</emphasis></mathphrase>
</inlineequation> values.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><code>marker</code></term>
<listitem>
<para>Given a string value <inlineequation>
<mathphrase><emphasis>x</emphasis></mathphrase>
</inlineequation>, return container names
greater in value than the specified
marker.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><code>end_marker</code></term>
<listitem>
<para>Given a string value <inlineequation>
<mathphrase><emphasis>x</emphasis></mathphrase>
</inlineequation>, return container names less
in value than the specified marker.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><code>format</code></term>
<listitem>
<para>Specify either <code>json</code> or
<code>xml</code> to return the respective
serialized response.</para>
</listitem>
</varlistentry>
</variablelist>
<para>At this time, a <code>prefix</code> query parameter is
not supported at the account level.</para>
<example>
<title>List Containers HTTP Request</title>
<literallayout class="monospaced"><xi:include href="samples/containers-list-req.txt" parse="text"/></literallayout>
</example>
<para>A list of containers is returned in the response body,
one container per line. A 204 (No Content) HTTP return
code will be passed back if the account has no
containers.</para>
<example>
<title>List Containers HTTP Response</title>
<literallayout class="monospaced"><xi:include href="samples/containers-list-resp.txt" parse="text"/></literallayout>
</example>
<section xml:id="s_serializedlistoutput">
<title>Serialized List Output</title>
<para>If a <code>format=xml</code> or
<code>format=json</code> argument is appended to
the storage account URL, the service serves extended
container information serialized in the chosen format.
The sample responses are formatted for readability. </para>
<para>The following HTTP request asks for a JSON response,
so the response returns an HTTP header and a JSON
response.</para>
<example>
<title>Get Containers Details HTTP and JSON
Request</title>
<literallayout class="monospaced"><xi:include href="samples/container-get-details-json-req.txt" parse="text"/></literallayout>
</example>
<example>
<title>Get Containers Details HTTP and JSON
Response</title>
<literallayout class="monospaced"><xi:include href="samples/container-get-details-http-json-resp.txt" parse="text"/></literallayout>
<programlisting language="json"><xi:include href="samples/container-get-details-resp.json" parse="text"/></programlisting>
</example>
<para>The following HTTP request asks for an XML response,
so the response returns an HTTP header and an XML
response.</para>
<example>
<title>Containers Details HTTP and XML Request</title>
<literallayout class="monospaced"><xi:include href="samples/container-get-details-http-xml-resp.txt" parse="text"/></literallayout>
</example>
<example>
<title>Containers Details HTTP and XML
Response</title>
<literallayout class="monospaced"><xi:include href="samples/container-get-details-http-xml-resp.txt" parse="text"/></literallayout>
<programlisting language="xml"><xi:include href="samples/container-get-details-resp.xml" parse="text"/></programlisting>
</example>
</section>
<section xml:id="s_list-large-number-containers">
<title>Controlling a Large List of Containers</title>
<para>The system returns a maximum of 10,000 container
names per request. To retrieve subsequent container
names, another request must be made with the 'marker'
parameter. The marker indicates where the last list
left off; the system returns container names greater
than this marker, up to 10,000 again. Note that the
marker value should be URL-encoded prior to sending
the HTTP request.</para>
<para>If 10,000 is larger than desired, use the 'limit'
parameter.</para>
<para>If the number of container names returned equals the
limit given (or 10,000 if no limit is given), you may
assume there are more container names.</para>
<example>
<title>List Large Number of Containers</title>
<para>For example, let's use a listing of five
container names:</para>
<literallayout class="monospaced">apples
bananas
kiwis
oranges
pears</literallayout>
<para>We'll use a limit of two to show how things
work:</para>
<literallayout class="monospaced"><xi:include href="samples/large-container-list-req.txt" parse="text"/></literallayout>
<literallayout class="monospaced">apples
bananas</literallayout>
<para>Because we received two items back, we can assume
there are more container names to list, so we make
another request with a marker of the last item
returned:</para>
<literallayout class="monospaced"><xi:include href="samples/large-container-list-filter-req.txt" parse="text"/></literallayout>
<literallayout class="monospaced">kiwis
oranges</literallayout>
<para>Again, two items are returned; there might be
more:</para>
<literallayout class="monospaced"><xi:include href="samples/large-container-list-filter2-req.txt" parse="text"/></literallayout>
<literallayout class="monospaced">pears</literallayout>
<para>With this one-item response we received less
than the limit number of container names,
indicating that this is the end of the
list.</para>
<para>By using <code>end_marker</code> we can limit
the result set to container names less than the
given value. </para>
<literallayout class="monospaced"><xi:include href="samples/large-container-list-filter-end-marker-req.txt" parse="text"/></literallayout>
<literallayout class="monospaced">apples
bananas
kiwis</literallayout>
</example>
</section>
</section>
<section xml:id="retrieve-account-metadata">
<title>Get Account Metadata</title>
<para>&HEAD; operations against an account are performed to
retrieve the number of containers and the total bytes
stored in OpenStack Object Storage for the account. This
information is returned in two custom headers,
<code>X-Account-Container-Count</code> and
<code>X-Account-Bytes-Used</code>. Since the storage
system is designed to store large amounts of data, care
should be taken when representing the total bytes response
as an integer; when possible, convert it to a 64-bit
unsigned integer if your platform supports that primitive
type.</para>
<example>
<title>Get Account Metadata HTTP Request</title>
<literallayout class="monospaced"><xi:include href="samples/account-get-metadata-req.txt" parse="text"/></literallayout>
</example>
<para>The HTTP return code will be 204 (No Content) if the
request succeeds. A 401 (Unauthorized) will be returned
for an invalid account or access key.</para>
<example>
<title>Get Account Metadata HTTP Response</title>
<literallayout class="monospaced"><xi:include href="samples/account-get-metadata-resp.txt" parse="text"/></literallayout>
</example>
</section>
<section xml:id="create-update-account-metadata">
<title>Create or Update Account Metadata</title>
<para> You can associate custom metadata headers with the
account level URI. These headers must take the format
<code>X-Account-Meta-*</code>. </para>
<para> To create or update an account metadata header use the
&POST; query. Subsequent requests for the same key/value
pair overwrite the previous value. </para>
<example>
<title>Update Account Metadata HTTP Request</title>
<literallayout class="monospaced"><xi:include href="samples/account-update-metadata-req.txt" parse="text"/></literallayout>
</example>
<para> No response body is returned. A status code of 204 (No
Content) indicates success. </para>
<example>
<title>Update Account Metadata HTTP Response</title>
<literallayout class="monospaced"><xi:include href="samples/account-update-metadata-resp.txt" parse="text"/></literallayout>
</example>
<para>To confirm your metadata changes, perform a &HEAD;
request on the account. Do not send the metadata in your
&HEAD; request.</para>
<example>
<title>View Account Metadata HTTP Request</title>
<literallayout class="monospaced"><xi:include href="samples/account-view-metadata-req.txt" parse="text"/></literallayout>
</example>
<example>
<title>View Account Metadata HTTP Response</title>
<literallayout class="monospaced"><xi:include href="samples/account-view-metadata-resp.txt" parse="text"/></literallayout>
</example>
</section>
<section xml:id="delete-account-metadata">
<title>Delete Account Metadata</title>
<para>To delete a metadata header send an empty value for that
particular header, such as
<code>X-Account-Meta-Book</code>. </para>
<para>If the tool you're using to communicate with Swift
doesn't support sending empty headers (such as older
versions of cURL) send the header
"X-Remove-Account-Meta-<replaceable>name</replaceable>:
<replaceable>arbitrary value</replaceable>", such as
<code>X-Remove-Account-Meta-Book: x</code>. The
<emphasis>value</emphasis> is ignored.</para>
<example>
<title>Delete Account Metadata HTTP Request</title>
<literallayout class="monospaced"><xi:include href="samples/account-delete-metadata-req.txt" parse="text"/></literallayout>
<para> No response body is returned. A status code of 204
(No Content) indicates success. </para>
</example>
</section>
</section>

View File

@@ -51,11 +51,13 @@
<year>2010</year>
<year>2011</year>
<year>2012</year>
<year>2013</year>
<holder>OpenStack, LLC</holder>
</copyright>
<releaseinfo>API v1</releaseinfo>
<productname>OpenStack Object Storage</productname>
<pubdate>2012-09-04</pubdate>
<!-- <pubdate>2012-09-04</pubdate> -->
<pubdate>2013-02-22</pubdate>
<legalnotice role="apache2">
<annotation>
<remark>Copyright details are filled in by the template.</remark>
@@ -68,6 +70,17 @@
(<abbrev>API</abbrev>). </para>
</abstract>
<revhistory>
<revision>
<date>2013-02-2</date>
<revdescription>
<itemizedlist spacing="compact">
<listitem>
<para>Moved code samples into separate files for content sharing.
</para>
</listitem>
</itemizedlist>
</revdescription>
</revision>
<revision>
<date>2012-09-12</date>
<revdescription>
@@ -173,4 +186,6 @@
<xi:include href="object-api-general.xml"/>
<xi:include href="object-api-storage-services.xml"/>
<xi:include href="object-api-troubleshooting-examples.xml"/>
<xi:include href="object-api-dochistory.xml"/>
<xi:include href="object-api-resources.xml"/>
</book>

View File

@@ -0,0 +1,4 @@
POST /<api version>/<account> HTTP/1.1
Host: storage.clouddrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
X-Remove-Account-Meta-Book: x

View File

@@ -0,0 +1,3 @@
HEAD /<api version>/<account> HTTP/1.1
Host: storage.swiftdrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb

View File

@@ -0,0 +1,5 @@
HTTP/1.1 204 No Content
Date: Thu, 07 Jun 2010 18:57:07 GMT
Server: Apache
X-Account-Container-Count: 3
X-Account-Bytes-Used: 323479

View File

@@ -0,0 +1,5 @@
POST /<api version>/<account> HTTP/1.1
Host: storage.clouddrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
X-Account-Meta-Book: MobyDick
X-Account-Meta-Subject: Whaling

View File

@@ -0,0 +1,4 @@
HTTP/1.1 204 No Content
Content-Length: 0
Content-Type: text/html; charset=UTF-8
Date: Sat, 09 Jun 2012 19:16:29 GMT

View File

@@ -0,0 +1,3 @@
HEAD /<api version>/<account> HTTP/1.1
Host: storage.clouddrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb

View File

@@ -0,0 +1,10 @@
HTTP/1.1 204 No Content
X-Account-Meta-Book: MobyDick
X-Account-Meta-Subject: Whaling
X-Account-Object-Count: 5
X-Timestamp: 1323466696.21566
X-Account-Container-Count: 5
X-Account-Bytes-Used: 46988
Accept-Ranges: bytes
Content-Length: 0
Date: Sat, 09 Jun 2012 19:16:59 GMT

View File

@@ -0,0 +1,4 @@
GET /v1.0 HTTP/1.1
Host: auth.api.yourcloud.com
X-Auth-User: jdoe
X-Auth-Key: a86850deb2742ec3cb41518e26aa2d89

View File

@@ -0,0 +1,7 @@
HTTP/1.1 204 No Content
Date: Mon, 12 Nov 2010 15:32:21 GMT
Server: Apache
X-Storage-Url: https://storage.swiftdrive.com/v1/CF_xer7_34
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
Content-Length: 0
Content-Type: text/plain; charset=UTF-8

View File

@@ -0,0 +1,5 @@
PUT /<api version>/<account>/<container>/<object> HTTP/1.1
Host: storage.swiftdrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
Transfer-Encoding: chunked
X-Object-Meta-PIN: 1234

View File

@@ -0,0 +1,5 @@
19
A bunch of data broken up
D
into chunks.
0

View File

@@ -0,0 +1,4 @@
PUT /<api version>/<account>/<container> HTTP/1.1
Host: storage.clouddrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
X-Container-Meta-InspectedBy: JackWolf

View File

@@ -0,0 +1,4 @@
HTTP/1.1 201 Created
Date: Thu, 07 Jun 2010 18:50:19 GMT
Server: Apache
Content-Type: text/plain; charset=UTF-8

View File

@@ -0,0 +1,3 @@
PUT /<api version>/<account>/<container> HTTP/1.1
Host: storage.swiftdrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb

View File

@@ -0,0 +1,4 @@
HTTP/1.1 201 Created
Date: Thu, 07 Jun 2007 18:50:19 GMT
Server: Apache
Content-Type: text/plain; charset=UTF-8

View File

@@ -0,0 +1,4 @@
POST /<api version>/<account>/<container> HTTP/1.1
Host: storage.clouddrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
X-Remove-Container-Meta-Book: x

View File

@@ -0,0 +1,3 @@
DELETE /<api version>/<account>/<container> HTTP/1.1
Host: storage.swiftdrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb

View File

@@ -0,0 +1,5 @@
HTTP/1.1 204 No Content
Date: Thu, 07 Jun 2010 18:57:07 GMT
Server: Apache
Content-Length: 0
Content-Type: text/plain; charset=UTF-8

View File

@@ -0,0 +1,4 @@
HTTP/1.1 200 OK
Date: Tue, 25 Nov 2008 19:39:13 GMT
Server: Apache
Content-Type: application/json; charset=utf-8

View File

@@ -0,0 +1,4 @@
HTTP/1.1 200 OK
Date: Tue, 25 Nov 2008 19:42:35 GMT
Server: Apache
Content-Type: application/xml; charset=utf-8

View File

@@ -0,0 +1,4 @@
GET /<api version>/<account>?format=json HTTP/1.1
Host: storage.swiftdrive.com
Content-Length: 0
X-Storage-Token: 182f9c0af0e828cfe3281767d29d19f4

View File

@@ -0,0 +1,4 @@
[
{"name":"test_container_1", "count":2, "bytes":78},
{"name":"test_container_2", "count":1, "bytes":17}
]

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<account name="MichaelBarton">
<container>
<name>test_container_1</name>
<count>2</count>
<bytes>78</bytes>
</container>
<container>
<name>test_container_2</name>
<count>1</count>
<bytes>17</bytes>
</container>
</account>

View File

@@ -0,0 +1,4 @@
GET /<api version>/<account>?format=xml HTTP/1.1
Host: storage.swiftdrive.com
Content-Length: 0
X-Storage-Token: 182f9c0af0e828cfe3281767d29d19f4

View File

@@ -0,0 +1,3 @@
HEAD /<api version>/<account>/<container> HTTP/1.1
Host: storage.swiftdrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb

View File

@@ -0,0 +1,6 @@
HTTP/1.1 204 No Content
Date: Wed, 11 Jul 2010 19:37:41 GMT
Content-type: text/html
X-Container-Object-Count: 7
X-Container-Bytes-Used: 413
X-Container-Meta-InspectedBy: JackWolf

View File

@@ -0,0 +1,5 @@
POST /<api version>/<account>/<container>/ HTTP/1.1
Host: storage.clouddrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
X-Container-Meta-Book: MobyDick
X-Container-Meta-Subject: Whaling

View File

@@ -0,0 +1,5 @@
HTTP/1.1 204 No Content
Date: Thu, 07 Mar 2012 20:42:51 GMT
Server: Apache
Content-Length: 0
Content-Type: text/plain; charset=UTF-8

View File

@@ -0,0 +1,3 @@
HEAD /<api version>/<account>/<container>/<object> HTTP/1.1
Host: storage.clouddrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb

View File

@@ -0,0 +1,9 @@
HTTP/1.1 204 No Content
X-Container-Object-Count: 0
X-Trans-Id: tx028b40d228534c759f4d5fa69f8cf7fd
X-Container-Meta-Book: MobyDick
X-Container-Meta-Subject: Whaling
Accept-Ranges: bytes
Date: Mon, 12 Mar 2012 16:40:20 GMT
Content-Length: 0
X-Container-Bytes-Used: 0

View File

@@ -0,0 +1,3 @@
GET /<api version>/<account> HTTP/1.1
Host: storage.swiftdrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb

View File

@@ -0,0 +1,10 @@
HTTP/1.1 200 Ok
Date: Thu, 07 Jun 2010 18:57:07 GMT
Server: Apache
Content-Type: text/plain; charset=UTF-8
Content-Length: 32
images
movies
documents
backups

View File

@@ -0,0 +1,5 @@
PUT /<api version>/<account>/<container>/<object> HTTP/1.1
Host: storage.clouddrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
Content-Type: image/tiff
Content-Disposition: attachment; filename=platmap.tif

View File

@@ -0,0 +1,5 @@
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 @@
swift post -m 'web-error:error.html' container

View File

@@ -0,0 +1 @@
swift post -m 'web-listings-css:listings.css' container

View File

@@ -0,0 +1,3 @@
GET /<api version><account>?end_marker=oranges
Host: storage.swiftdrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb

View File

@@ -0,0 +1,3 @@
GET /<api version>/<account>?limit=2&marker=bananas
Host: storage.swiftdrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb

View File

@@ -0,0 +1,3 @@
GET /<api version>/<account>?limit=2&marker=oranges
Host: storage.swiftdrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb

View File

@@ -0,0 +1,3 @@
GET /<api version>/<account>?limit=2
Host: storage.swiftdrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb

View File

@@ -0,0 +1,6 @@
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

View File

@@ -0,0 +1,6 @@
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

View File

@@ -0,0 +1 @@
<METHOD> /v1/<account> HTTP/1.1

View File

@@ -0,0 +1,4 @@
PUT /<api version&gt;/<account&gt;/<container&gt;/<object&gt; HTTP/1.1
Host: storage.clouddrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
Origin: http://storage.clouddrive.com

View File

@@ -0,0 +1,5 @@
PUT /<api version>/<account>/<container>/<destobject> HTTP/1.1
Host: <storage URL>
X-Auth-Token: <some-auth-token>
X-Copy-From: /<container>/<sourceobject>
Content-Length: 0

View File

@@ -0,0 +1,4 @@
COPY /<api version>/&lt;account>/<container>/<sourceobject> HTTP/1.1
Host: <storage URL>
X-Auth-Token: <some-auth-token>
Destination: /<container>/<destobject>

View File

@@ -0,0 +1,6 @@
PUT /<api version>/<account>/<container>/<object> HTTP/1.1
Host: storage.swiftdrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
ETag: 8a964ee2a5e88be344f36c22562a6486
Content-Length: 512000
X-Object-Meta-PIN: 1234

View File

@@ -0,0 +1,6 @@
HTTP/1.1 201 Created
Date: Thu, 07 Jun 2010 18:57:07 GMT
Server: Apache
ETag: d9f5eb4bba4e2f2f046e54611bc8196b
Content-Length: 0
Content-Type: text/plain; charset=UTF-8

View File

@@ -0,0 +1,5 @@
PUT /<api version>/<account>/<container>/<object> HTTP/1.1
Host: storage.clouddrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
Content-Type: image/jpeg
X-Delete-After: 864000

View File

@@ -0,0 +1,5 @@
PUT /<api version>/<account>/<container>/<object> HTTP/1.1
Host: storage.clouddrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
Content-Type: image/jpeg
X-Delete-At: 1339429105

View File

@@ -0,0 +1,3 @@
DELETE /<api version>/<account>/<container>/<object> HTTP/1.1
Host: storage.swiftdrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb

View File

@@ -0,0 +1,4 @@
HTTP/1.1 204 No Content
Date: Thu, 07 Jun 2010 20:59:39 GMT
Server: Apache
Content-Type: text/plain; charset=UTF-8

View File

@@ -0,0 +1,3 @@
GET /<api version>/<account>/<container>/<object> HTTP/1.1
Host: storage.swiftdrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb

View File

@@ -0,0 +1,7 @@
HTTP/1.1 200 Ok
Date: Wed, 11 Jul 2010 19:37:41 GMT
Server: Apache
Last-Modified: Fri, 12 Jun 2010 13:40:18 GMT
ETag: b0dffe8254d152d8fd28f3c5e0404a10
Content-type: text/html
Content-Length: 512000

View File

@@ -0,0 +1,3 @@
GET /<api version>/<account>/<container>[?parm=value] HTTP/1.1
Host: storage.swiftdrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb

View File

@@ -0,0 +1,14 @@
HTTP/1.1 200 Ok
Date: Thu, 07 Jun 2010 18:50:19 GMT
Server: Apache
Content-Type: text/plain; charset=UTF-8
Content-Length: 171
kate_beckinsale.jpg
How To Win Friends And Influence People.pdf
moms_birthday.jpg
poodle_strut.mov
Disturbed - Down With The Sickness.mp3
army_of_darkness.avi
the_mad.avi

View File

@@ -0,0 +1,3 @@
HEAD /&lt;api version>/&lt;account>/&lt;container>/&lt;object> HTTP/1.1
Host: storage.swiftdrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb

View File

@@ -0,0 +1,11 @@
HTTP/1.1 200 OK
Date: Thu, 07 Jun 2010 20:59:39 GMT
Server: Apache
Last-Modified: Fri, 12 Jun 2010 13:40:18 GMT
ETag: 8a964ee2a5e88be344f36c22562a6486
Content-Length: 512000
Content-Type: text/plain; charset=UTF-8
X-Object-Meta-Meat: Bacon
X-Object-Meta-Fruit: Bacon
X-Object-Meta-Veggie: Bacon
X-Object-Meta-Dairy: Bacon

View File

@@ -0,0 +1,5 @@
POST /<api version>/<account>/<container>/<object> HTTP/1.1
Host: storage.swiftdrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
X-Object-Meta-Fruit: Apple
X-Object-Meta-Veggie: Carrot

View File

@@ -0,0 +1,5 @@
HTTP/1.1 202 Accepted
Date: Thu, 07 Jun 2010 20:59:39 GMT
Server: Apache
Content-Length: 0
Content-Type: text/plain; charset=UTF-8

View File

@@ -0,0 +1,4 @@
GET /<api version>/<account>/<container>?format=json HTTP/1.1
Host: storage.swiftdrive.com
Content-Length: 0
X-Storage-Token: 182f9c0af0e828cfe3281767d29d19f4

View File

@@ -0,0 +1,5 @@
HTTP/1.1 200 OK
Date: Tue, 25 Nov 2008 19:39:13 GMT
Server: Apache
Content-Length: 387
Content-Type: application/json; charset=utf-8

View File

@@ -0,0 +1,3 @@
GET /<api version>/<account>/<container>?format=xml HTTP/1.1
Host: storage.swiftdrive.com
X-Storage-Token: 182f9c0af0e828cfe3281767d29d19f4

View File

@@ -0,0 +1,5 @@
HTTP/1.1 200 OK
Date: Tue, 25 Nov 2008 19:42:35 GMT
Server: Apache
Content-Length: 643
Content-Type: application/xml; charset=utf-8

View File

@@ -0,0 +1,12 @@
[
{"name":"test_obj_1",
"hash":"4281c348eaf83e70ddce0e07221c3d28",
"bytes":14,
"content_type":"application\/octet-stream",
"last_modified":"2009-02-03T05:26:32.612278"},
{"name":"test_obj_2",
"hash":"b039efe731ad111bc1b0ef221c3849d0",
"bytes":64,
"content_type":"application\/octet-stream",
"last_modified":"2009-02-03T05:26:32.612278"},
]

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<container name="test_container_1">
<object>
<name>test_object_1</name>
<hash>4281c348eaf83e70ddce0e07221c3d28</hash>
<bytes>14</bytes>
<content_type>application/octet-stream</content_type>
<last_modified>2009-02-03T05:26:32.612278</last_modified>
</object>
<object>
<name>test_object_2</name>
<hash>b039efe731ad111bc1b0ef221c3849d0</hash>
<bytes>64</bytes>
<content_type>application/octet-stream</content_type>
<last_modified>2009-02-03T05:26:32.612278</last_modified>
</object>
</container>

View File

@@ -0,0 +1,8 @@
GET /<api version><account>/<container>?end_marker=jonagold
Host: storage.swiftdrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
gala
grannysmith
honeycrisp

View File

@@ -0,0 +1,7 @@
GET /<api version>/<account>/<container>?limit=2&marker=grannysmith
Host: storage.swiftdrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
honeycrisp
jonagold

View File

@@ -0,0 +1,6 @@
GET /<api version>/<account>/<container>?limit=2&marker=jonagold
Host: storage.swiftdrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
reddelicious

View File

@@ -0,0 +1,7 @@
GET /<api version>/<account>/<container>?limit=2
Host: storage.swiftdrive.com
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
gala
grannysmith

View File

@@ -0,0 +1,20 @@
[DEFAULT]
...
[pipeline:main]
pipeline = healthcheck cache tempauth staticweb proxy-server
...
[filter:staticweb]
use = egg:swift#staticweb
# Seconds to cache container x-container-meta-web-* header values.
# cache_timeout = 300
# You can override the default log routing for this filter here:
# set log_name = staticweb
# set log_facility = LOG_LOCAL0
# set log_level = INFO
# set access_log_name = staticweb
# set access_log_facility = LOG_LOCAL0
# set access_log_level = INFO
# set log_headers = False

View File

@@ -0,0 +1,6 @@
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/object/segments