Complete information for Range header of GET object
The range header allows to specify multiple ranges. Add some examples using the Range header. Change-Id: I28ef60e5d7c8dc2a8973a2c3548cbef3128ff25a
This commit is contained in:
parent
5682e3380e
commit
d313263bb7
@ -0,0 +1,4 @@
|
||||
GET /<api version>/<account>/<container>/<object> HTTP/1.1
|
||||
Host: storage.swiftdrive.com
|
||||
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
|
||||
Range: bytes=4-6
|
@ -0,0 +1,10 @@
|
||||
HTTP/1.1 206 Partial Content
|
||||
Content-Length: 3
|
||||
Content-Type: application/octet-stream
|
||||
Accept-Ranges: bytes
|
||||
Last-Modified: Wed, 11 Dec 2013 01:03:26 GMT
|
||||
Content-Range: bytes 4-6/10
|
||||
Etag: 3749f52bb326ae96782b42dc0a97b4c1
|
||||
Date: Wed, 11 Dec 2013 06:13:04 GMT
|
||||
|
||||
456
|
@ -0,0 +1,4 @@
|
||||
GET /<api version>/<account>/<container>/<object> HTTP/1.1
|
||||
Host: storage.swiftdrive.com
|
||||
X-Auth-Token: eaaafd18-0fed-4b3a-81b4-663c99ec1cbb
|
||||
Range: bytes=1-3,2-5
|
@ -0,0 +1,20 @@
|
||||
HTTP/1.1 206 Partial Content
|
||||
Content-Length: 265
|
||||
Content-Type: multipart/byteranges;boundary=4789b20f24cc4d2a8da2e552e151e6fe
|
||||
Accept-Ranges: bytes
|
||||
Last-Modified: Wed, 11 Dec 2013 01:03:26 GMT
|
||||
Etag: 3749f52bb326ae96782b42dc0a97b4c1
|
||||
Date: Wed, 11 Dec 2013 06:13:41 GMT
|
||||
|
||||
|
||||
--4789b20f24cc4d2a8da2e552e151e6fe
|
||||
Content-Type: application/octet-stream
|
||||
Content-Range: bytes 1-3/10
|
||||
|
||||
123
|
||||
--4789b20f24cc4d2a8da2e552e151e6fe
|
||||
Content-Type: application/octet-stream
|
||||
Content-Range: bytes 2-5/10
|
||||
|
||||
2345
|
||||
--4789b20f24cc4d2a8da2e552e151e6fe--
|
@ -11,38 +11,23 @@
|
||||
<!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>
|
||||
<para>An object represents the data and metadata for the files
|
||||
stored in the system. Through the ReST interface, you can
|
||||
include metadata for an object by adding custom HTTP headers
|
||||
to the request and the data payload as the request body.
|
||||
Objects cannot exceed 5 GB and must have names that do not
|
||||
exceed 1024 bytes after URL encoding. However, you can segment
|
||||
a large object into 5 GB segments and upload the segments.
|
||||
Then, you can download the segments as a single concatenated
|
||||
object. You can use HTTP requests to work with the segments
|
||||
and manifests directly.</para>
|
||||
<informaltable rules="all">
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<td colspan="1">Verb</td>
|
||||
@ -91,84 +76,151 @@ format="SVG" scale="60"/>
|
||||
</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
|
||||
<para>Perform &GET; operations against an object to get object
|
||||
data.</para>
|
||||
<para>You can perform conditional &GET; requests by using the
|
||||
following HTTP headers in the request:</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><literal>If-Match</literal></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><literal>If-None-Match</literal></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><literal>If-Modified-Since</literal></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><literal>If-Unmodified-Since</literal></para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>These headers are documented in <link
|
||||
xlink:href="http://www.ietf.org/rfc/rfc2616.txt"
|
||||
>http://www.ietf.org/rfc/rfc2616.txt</link>
|
||||
</para>
|
||||
>http://www.ietf.org/rfc/rfc2616.txt</link>.</para>
|
||||
<para>You can use the HTTP <code>Range</code> header to fetch
|
||||
portions of data by using one or more range
|
||||
specifications. To specify many ranges, separate the range
|
||||
specifications with a comma.</para>
|
||||
<para>The types of range specifications are:</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>If-Match</para>
|
||||
<para><emphasis role="bold">Byte range
|
||||
specification</emphasis>. Use
|
||||
FIRST_BYTE_OFFSET to specify the start of the data
|
||||
range, and LAST_BYTE_OFFSET to specify the end.
|
||||
You can omit the LAST_BYTE_OFFSET and if you do,
|
||||
the value defaults to the offset of the last byte
|
||||
of data.</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>
|
||||
<para><emphasis role="bold">Suffix byte range
|
||||
specification</emphasis>. Use LENGTH bytes to
|
||||
specify the length of the data range.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>The following forms of the header specify the following
|
||||
ranges of data:</para>
|
||||
<informaltable rules="all">
|
||||
<col width="50%"/>
|
||||
<col width="50%"/>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Header</th>
|
||||
<th>Range of object data</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<para><code>Range: bytes=-5</code></para></td>
|
||||
<td><para>The last 5 bytes.</para>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<para><code>Range:
|
||||
bytes=4-6</code></para></td>
|
||||
<td><para>Bytes 4 to 6 inclusive.</para></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<para><code>Range:
|
||||
bytes=2-2</code></para></td>
|
||||
<td><para>Byte 2, the third byte of the
|
||||
data.</para>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<para><code>Range: bytes=6-</code></para></td>
|
||||
<td><para>Byte 6 byte and after.</para>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<para><code>Range:
|
||||
bytes=1-3,2-5</code></para></td>
|
||||
<td><para>Bytes 1 to 3 inclusive, and bytes 2 to 5
|
||||
inclusive.</para>
|
||||
<para>The <code>Content-Type</code> of the
|
||||
response is then
|
||||
<code>multipart/byteranges</code>.</para>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</informaltable>
|
||||
<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 2xx
|
||||
(between 200 and 299, inclusive) indicates success; status 404
|
||||
(Not Found) is returned if no such object exists.</para>
|
||||
<para>The object data is returned in the response body. Object
|
||||
metadata is returned as HTTP headers. A status of
|
||||
2<replaceable>xx</replaceable> (between 200 and 299,
|
||||
inclusive) 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>
|
||||
<para>These examples include an object that contains 10 bytes
|
||||
of data: <literal>0123456789</literal>.</para>
|
||||
<example>
|
||||
<title>Get Object Details HTTP Request Using Range</title>
|
||||
<literallayout class="monospaced"><xi:include href="samples/object-get-range-req.txt" parse="text"/></literallayout>
|
||||
</example>
|
||||
<example>
|
||||
<title>Get Object Details HTTP Response When Using
|
||||
Range</title>
|
||||
<literallayout class="monospaced"><xi:include href="samples/object-get-range-resp.txt" parse="text"/></literallayout>
|
||||
</example>
|
||||
<example>
|
||||
<title>Get Object Details HTTP Request Using Multiple
|
||||
Ranges</title>
|
||||
<literallayout class="monospaced"><xi:include href="samples/object-get-ranges-req.txt" parse="text"/></literallayout>
|
||||
</example>
|
||||
<example>
|
||||
<title>Get Object Details HTTP Response When Using
|
||||
Multiple Ranges</title>
|
||||
<literallayout class="monospaced"><xi:include href="samples/object-get-ranges-resp.txt" parse="text"/></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>
|
||||
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 Object Storage 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>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 Object Storage 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
|
||||
@ -183,8 +235,8 @@ format="SVG" scale="60"/>
|
||||
<para>The object can be created with custom metadata via HTTP
|
||||
headers identified with the <code>X-Object-Meta-</code>
|
||||
prefix, or arbitrary headers set with the
|
||||
<literal>allowed_headers</literal> option in the object-server
|
||||
configuration.</para>
|
||||
<literal>allowed_headers</literal> option in the
|
||||
object-server configuration.</para>
|
||||
<example>
|
||||
<title>Create or Update Object HTTP Request</title>
|
||||
<literallayout class="monospaced"><xi:include href="samples/object-create-req.txt" parse="text"/></literallayout>
|
||||
@ -219,7 +271,7 @@ format="SVG" scale="60"/>
|
||||
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 see <xref
|
||||
linkend="large-object-creation"/>. </para>
|
||||
linkend="large-object-creation"/>.</para>
|
||||
<example>
|
||||
<title>Upload Unspecified Quantity of Content HTTP
|
||||
Request</title>
|
||||
@ -263,32 +315,33 @@ format="SVG" scale="60"/>
|
||||
<para>If you use the © operation using a manifest
|
||||
object as the source, the new object is a "normal"
|
||||
object (not segmented). If the total size of the
|
||||
source segment objects exceeds 5GB, the ©
|
||||
operation will fail. However, as explained later, you
|
||||
source segment objects exceeds 5 GB, the ©
|
||||
operation fails. However, as explained later, you
|
||||
can make a duplicate of the manifest object. This new
|
||||
object may be larger than 5GB. </para>
|
||||
object can be larger than 5 GB.</para>
|
||||
</note>
|
||||
<para>There are two types of manifest object as follows:<itemizedlist>
|
||||
<listitem>
|
||||
<para>Static Large Objects. The manifest object
|
||||
content is an ordered list of the names of the
|
||||
segment objects in json format. </para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Dynamic Large Objects. The manifest object
|
||||
has no content. However, it has
|
||||
<code>X-Object-Manifest</code> metadata.
|
||||
The value of this is
|
||||
<code><container>/<prefix></code>,
|
||||
where <code><container></code> is the name
|
||||
of the container where the segment objects are
|
||||
stored and <code><prefix></code> is a
|
||||
string that all the segment objects have in
|
||||
common.</para>
|
||||
</listitem>
|
||||
</itemizedlist>While both types of manifest objects have
|
||||
similar behavior, there are differences as explained in
|
||||
the following table.</para>
|
||||
<para>The manifest object type are:</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>Static large objects. The manifest object
|
||||
content is an ordered list of the names of the
|
||||
segment objects in json format.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>Dynamic large objects. The manifest object has
|
||||
no content. However, it has
|
||||
<code>X-Object-Manifest</code> metadata. The
|
||||
value of this is
|
||||
<code><container>/<prefix></code>, where
|
||||
<code><container></code> is the name of the
|
||||
container where the segment objects are stored and
|
||||
<code><prefix></code> is a string that all
|
||||
the segment objects have in common.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<para>While both types of manifest objects have similar
|
||||
behavior, there are differences as explained in the
|
||||
following table.</para>
|
||||
<table rules="all">
|
||||
<caption>Comparison of Static and Dynamic Large
|
||||
Objects</caption>
|
||||
@ -402,14 +455,19 @@ format="SVG" scale="60"/>
|
||||
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 and ensure that each object name is prefixed in such a way that
|
||||
it sorts in the order in which it should be concatenated. You also create and upload
|
||||
a manifest file. The manifest file is a zero-byte file with the extra
|
||||
X-Object-Manifest: <container>/<prefix> header, where <container>
|
||||
is the container the object segments are in and <prefix> is the common prefix
|
||||
for all the segments. The container and common prefix must be UTF-8 encoded and
|
||||
URL-encoded in the X-Object-Manifest header.</para>
|
||||
<para>To ensure the download works correctly, you must
|
||||
upload all the object segments to the same container
|
||||
and ensure that each object name is prefixed in such a
|
||||
way that it sorts in the order in which it should be
|
||||
concatenated. You also create and upload a manifest
|
||||
file. The manifest file is a zero-byte file with the
|
||||
extra X-Object-Manifest:
|
||||
<container>/<prefix> header, where
|
||||
<container> is the container the object segments
|
||||
are in and <prefix> is the common prefix for all
|
||||
the segments. The container and common prefix must be
|
||||
UTF-8 encoded and URL-encoded in the X-Object-Manifest
|
||||
header.</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
|
||||
@ -431,9 +489,8 @@ format="SVG" scale="60"/>
|
||||
</example>
|
||||
<para>No response body is returned. A status code of 2xx
|
||||
(between 200 and 299, inclusive) indicates a
|
||||
successful write; status 411 (Length Required)
|
||||
denotes a missing
|
||||
<code>Content-Length</code> or
|
||||
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
|
||||
@ -474,60 +531,59 @@ format="SVG" scale="60"/>
|
||||
</section>
|
||||
<section xml:id="static-large-objects">
|
||||
<title>Static Large Objects</title>
|
||||
<para> A Static Large Object is created in two steps:<orderedlist>
|
||||
<listitem>
|
||||
<para>Divide your content into pieces and
|
||||
create (i.e., upload) a segment object to
|
||||
contain each piece. You must record the
|
||||
<code>ETag</code> response header
|
||||
returned by the&PUT; operation.
|
||||
Alternatively, you can calculate the MD5
|
||||
checksum of the segment prior to uploading
|
||||
and include this in the <code>ETag</code>
|
||||
request header -- this ensures that the
|
||||
upload cannot corrupt your data.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>List the name of each segment object
|
||||
along with its size and MD5 checksum in
|
||||
order. Create a manifest object. You
|
||||
indicate that this is a manifest object by
|
||||
including the
|
||||
<code>?multipart-manifest=put</code>
|
||||
query string at the end of the manifest
|
||||
object name. </para>
|
||||
</listitem>
|
||||
</orderedlist>The body of the &PUT; request on the
|
||||
manifest object comprises a json list, where each
|
||||
element contains the following:<itemizedlist>
|
||||
<listitem>
|
||||
<para><code>path</code> - this is the
|
||||
container and object name in the following
|
||||
format:
|
||||
<code><container-name>/<object-name></code></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><code>etag</code> - this is the MD5
|
||||
checksum of the content of the segment
|
||||
object. This must match the
|
||||
<code>ETag</code> of that
|
||||
object.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><code>size_bytes</code> - this is the
|
||||
size of the segment object. This must
|
||||
match the <code>Content-Length</code> of
|
||||
that object</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>To create a static large object:</para>
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>Divide your content into pieces and create
|
||||
(upload) a segment object to contain each
|
||||
piece. You must record the <code>ETag</code>
|
||||
response header returned by the&PUT;
|
||||
operation. Alternatively, you can calculate
|
||||
the MD5 checksum of the segment prior to
|
||||
uploading and include this in the
|
||||
<code>ETag</code> request header. This
|
||||
ensures that the upload cannot corrupt your
|
||||
data.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>List the name of each segment object along
|
||||
with its size and MD5 checksum in order.
|
||||
Create a manifest object. You indicate that
|
||||
this is a manifest object by including the
|
||||
<code>?multipart-manifest=put</code> query
|
||||
string at the end of the manifest object
|
||||
name.</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
<para>The body of the &PUT; request on the manifest object
|
||||
comprises a json list, where each element contains the
|
||||
following:</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><code>path</code> - this is the container
|
||||
and object name in the following format:
|
||||
<code><container-name>/<object-name></code></para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><code>etag</code> - this is the MD5 checksum
|
||||
of the content of the segment object. This
|
||||
must match the <code>ETag</code> of that
|
||||
object.</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para><code>size_bytes</code> - this is the size
|
||||
of the segment object. This must match the
|
||||
<code>Content-Length</code> of that
|
||||
object</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
<example>
|
||||
<title>Static Large Object Manifest List</title>
|
||||
<para>This is an example containing three segment
|
||||
objects. In this example, we illustrate that in
|
||||
contrast to dynamic large objects, you can use a
|
||||
number of containers and the object names do not
|
||||
have to conform to a specific pattern.</para>
|
||||
objects. In this example, you can use several
|
||||
containers and the object names do not have to
|
||||
conform to a specific pattern, in contrast to
|
||||
dynamic large objects.</para>
|
||||
<literallayout class="monospaced"><xi:include href="samples/slo-manifest-example.txt" parse="text"/></literallayout>
|
||||
</example>
|
||||
<para>The <code>Content-Length</code> request header must
|
||||
@ -561,7 +617,7 @@ format="SVG" scale="60"/>
|
||||
<code>?multipart-manifest=get</code>. The
|
||||
resulting list will not be identically formatted as
|
||||
the manifest you originally used in the &PUT;
|
||||
operation. </para>
|
||||
operation.</para>
|
||||
<para>If you use the &DELETE; operation on a manifest
|
||||
object, the manifest object is deleted -- the segment
|
||||
objects are not affected. However, if you add the
|
||||
@ -579,11 +635,12 @@ format="SVG" scale="60"/>
|
||||
</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 Object Storage
|
||||
API requests. These headers are supported with the Object Storage
|
||||
API. You can read more about the definition of the Access-Control-
|
||||
<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 Object Storage API requests. These
|
||||
headers are supported with the Object Storage 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>
|
||||
@ -612,13 +669,14 @@ format="SVG" scale="60"/>
|
||||
<para>Origin</para>
|
||||
</listitem>
|
||||
</itemizedlist></para>
|
||||
<para>You can assign these headers to objects only. </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 Object Storage repository are indeed from
|
||||
the correct origination:</para>
|
||||
<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 Object Storage
|
||||
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>
|
||||
@ -670,7 +728,7 @@ format="SVG" scale="60"/>
|
||||
<!-- 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>
|
||||
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
|
||||
@ -704,7 +762,7 @@ format="SVG" scale="60"/>
|
||||
<section xml:id="Object_Versioning-e1e3230">
|
||||
<!-- begin 4.3.2.7 -->
|
||||
<title>Object Versioning</title>
|
||||
<para>Object Versioning allows you to store multiple versions
|
||||
<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
|
||||
@ -715,23 +773,28 @@ format="SVG" scale="60"/>
|
||||
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. The name of the container must be UTF-8 encoded and then
|
||||
URL-encoded before putting into the <code>X-Versions-Location</code> header. 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>
|
||||
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. The name of the container
|
||||
must be UTF-8 encoded and then URL-encoded before putting
|
||||
into the <code>X-Versions-Location</code> header. 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>
|
||||
schema below.</para>
|
||||
<para>
|
||||
<emphasis>Naming Schema:</emphasis> Non-current versions
|
||||
are assigned the name
|
||||
@ -739,37 +802,37 @@ format="SVG" scale="60"/>
|
||||
length is the 3-character zero-padded hexadecimal
|
||||
character length of the <object_name> and
|
||||
<timestamp> is when the it was initially created as
|
||||
a current version. </para>
|
||||
a current version.</para>
|
||||
<para>Any return status in the 2xx range, such as 202
|
||||
(Accepted), denotes success. Status codes in the 4xx or 5xx
|
||||
range denote 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
|
||||
(Accepted), denotes success. Status codes in the 4xx or
|
||||
5xx range denote 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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
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>
|
||||
metadata by sending an empty key value.</para>
|
||||
<example>
|
||||
<title>Object Versioning with cURL</title>
|
||||
<para>Make sure a version-storing container exists,
|
||||
@ -780,39 +843,30 @@ format="SVG" scale="60"/>
|
||||
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>
|
||||
current version is the container "current".</para>
|
||||
<para>Create a container named versions.</para>
|
||||
<literallayout class="monospaced"> curl -i -XPUT -H "X-Auth-Token: <token>" http://<storage_url>/versions</literallayout>
|
||||
<screen><prompt>$</prompt> <userinput>curl -i -XPUT -H "X-Auth-Token: <token>" http://<storage_url>/versions</userinput></screen>
|
||||
<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: <token>" \
|
||||
-H "X-Versions-Location: versions" http://<storage_url>/current
|
||||
</literallayout>
|
||||
<para>Create an object (the first version): </para>
|
||||
<literallayout class="monospaced">
|
||||
curl -i -XPUT --data-binary 1 -H "X-Auth-Token: <token>" \
|
||||
http://<storage_url>/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: <token>" \
|
||||
http://<storage_url>/current/myobject
|
||||
</literallayout>
|
||||
<para>See a listing of the older versions of the object: </para>
|
||||
<literallayout class="monospaced">
|
||||
curl -i -H "X-Auth-Token: <token>" \
|
||||
http://<storage_url>/versions?prefix=008myobject/
|
||||
</literallayout>
|
||||
<screen><prompt>$</prompt> <userinput>curl -i -XPUT -H "X-Auth-Token: <token>" \
|
||||
-H "X-Versions-Location: versions" http://<storage_url>/current</userinput></screen>
|
||||
<para>Create an object (the first version):</para>
|
||||
<screen><prompt>$</prompt> <userinput>curl -i -XPUT --data-binary 1 -H "X-Auth-Token: <token>" \
|
||||
http://<storage_url>/current/myobject</userinput></screen>
|
||||
<para>Now create a new version of that object:</para>
|
||||
<screen><prompt>$</prompt> <userinput>curl -i -XPUT --data-binary 2 -H "X-Auth-Token: <token>" \
|
||||
http://<storage_url>/current/myobject</userinput></screen>
|
||||
<para>See a listing of the older versions of the
|
||||
object:</para>
|
||||
<screen><prompt>$</prompt> <userinput>curl -i -H "X-Auth-Token: <token>" \
|
||||
http://<storage_url>/versions?prefix=008myobject/</userinput></screen>
|
||||
<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: <token>" \
|
||||
http://<storage_url>/current/myobject
|
||||
curl -i -H "X-Auth-Token: <token>" \
|
||||
http://<storage_url>/versions?prefix=008myobject/
|
||||
</literallayout>
|
||||
that the older version is gone:</para>
|
||||
<screen><prompt>$</prompt> <userinput>curl -i -XDELETE -H "X-Auth-Token: <token>" \
|
||||
http://<storage_url>/current/myobject</userinput></screen>
|
||||
<screen><userinput><prompt>$</prompt> curl -i -H "X-Auth-Token: <token>" \
|
||||
http://<storage_url>/versions?prefix=008myobject/</userinput></screen>
|
||||
</example>
|
||||
</section>
|
||||
<section xml:id="copy-object">
|
||||
@ -825,13 +879,16 @@ format="SVG" scale="60"/>
|
||||
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”. The container and object name must be UTF-8 encoded and then
|
||||
URL-encoded. Also, the <code>X-Copy-From</code> &PUT; requests require a Content-Length
|
||||
header, even if it is zero (0).</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”. The container and object name must
|
||||
be UTF-8 encoded and then URL-encoded. 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>
|
||||
@ -840,7 +897,7 @@ format="SVG" scale="60"/>
|
||||
© 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>
|
||||
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>
|
||||
@ -875,7 +932,7 @@ format="SVG" scale="60"/>
|
||||
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>
|
||||
to change the content type of an existing object.</para>
|
||||
</section>
|
||||
<section xml:id="delete-object">
|
||||
<title>Delete Object</title>
|
||||
@ -896,14 +953,14 @@ format="SVG" scale="60"/>
|
||||
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>
|
||||
>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 2xx (
|
||||
between 200 and 299, inclusive) indicates success; status code
|
||||
404 (Not Found) is returned when the object does not
|
||||
between 200 and 299, inclusive) indicates success; status
|
||||
code 404 (Not Found) is returned when the object does not
|
||||
exist.</para>
|
||||
<example>
|
||||
<title>Object Delete HTTP Response</title>
|
||||
@ -923,7 +980,7 @@ format="SVG" scale="60"/>
|
||||
<para>No response body is returned. Metadata is returned as
|
||||
HTTP headers. A status code of 2xx (between 200 and 299,
|
||||
inclusive) indicates success; status 404 (Not Found) is
|
||||
returned when the object does not exist. </para>
|
||||
returned when the object does not exist.</para>
|
||||
<example>
|
||||
<title>Get Object Metadata HTTP Response</title>
|
||||
<literallayout class="monospaced"><xi:include href="samples/object-metadata-resp.txt" parse="text"/></literallayout>
|
||||
@ -942,7 +999,7 @@ format="SVG" scale="60"/>
|
||||
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>
|
||||
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
|
||||
@ -952,9 +1009,9 @@ format="SVG" scale="60"/>
|
||||
<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 2xx
|
||||
(between 200 and 299, inclusive) indicates success; status 404
|
||||
(Not Found) is returned if the requested object does not
|
||||
exist. </para>
|
||||
(between 200 and 299, inclusive) 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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user