Merge "Add temp URL and form POST to dev guide"

This commit is contained in:
Jenkins 2014-01-28 18:59:59 +00:00 committed by Gerrit Code Review
commit af2df10d8f
7 changed files with 494 additions and 4 deletions

View File

@ -49,6 +49,7 @@
<year>2011</year>
<year>2012</year>
<year>2013</year>
<year>2014</year>
<holder>OpenStack Foundation</holder>
</copyright>
<releaseinfo>API v1</releaseinfo>
@ -66,6 +67,17 @@
Application Programming Interface (API) v1.</para>
</abstract>
<revhistory>
<revision>
<date>2014-01-24</date>
<revdescription>
<itemizedlist spacing="compact">
<listitem>
<para>Added information about form &POST; and
temporary URL middleware.</para>
</listitem>
</itemizedlist>
</revdescription>
</revision>
<revision>
<date>2013-10-16</date>
<revdescription>
@ -173,7 +185,7 @@
<para>Revised for OpenStack Object Storage use by
removing CDN references, Rackspace Cloud references,
and revised account examples and URLs for generic
implementations. Clarified that container and object
implementations. Clarified that container and object
names must be UTF-8 encoded.</para>
</listitem>
</itemizedlist>
@ -217,7 +229,7 @@
</revhistory>
</info>
<!-- Chapters are referred from the book file through these include statements. You can add additional chapters using these types of statements. -->
<xi:include href="ch_object-api-overview.xml"/>
<xi:include href="preface.xml"/>
<xi:include href="ch_object-api-general.xml"/>
<xi:include href="ch_object-api-storage-services.xml"/>
<xi:include href="ch_object-api-troubleshooting-examples.xml"/>

View File

@ -186,7 +186,7 @@ format="SVG" scale="60"/>
OpenStack Object Storage are performed using SSL over
HTTP (HTTPS) on TCP port 443.</para>
</note>
</section>
<xi:include href="section_object_api_tempurl.xml"/>
<xi:include href="section_object_api_formpost.xml"/>
</chapter>

View File

@ -0,0 +1,14 @@
&lt;![CDATA[
<form action="SWIFT_URL"
method="POST"
enctype="multipart/form-data">
<input type="hidden" name="redirect" value="REDIRECT_URL"/>
<input type="hidden" name="max_file_size" value="BYTES"/>
<input type="hidden" name="max_file_count" value="COUNT"/>
<input type="hidden" name="expires" value="UNIX_TIMESTAMP"/>
<input type="hidden" name="signature" value="HMAC"/>
<input type="file" name="FILE_NAME"/>
<br/>
<input type="submit"/>
</form>
]]&gt;

View File

@ -0,0 +1,4 @@
https://swift-cluster.example.com/v1/my_account/container/object
?temp_url_sig=da39a3ee5e6b4b0d3255bfef95601890afd80709
&temp_url_expires=1323479485
&filename=My+Test+File.pdf

View File

@ -0,0 +1,243 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section [
<!-- Useful for describing APIs -->
<!ENTITY POST '<command xmlns="http://docbook.org/ns/docbook">POST</command>'>
]>
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:m="http://www.w3.org/1998/Math/MathML"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:db="http://docbook.org/ns/docbook" version="5.0"
xml:id="form-post">
<title>Form POST middleware</title>
<?dbhtml stop-chunking?>
<para>You can upload objects directly to the Object Storage system
from a browser by using the form &POST; middleware. This
middleware uses account secret keys to generate a
cryptographic signature for the request. This means that you
do not need to send an authentication token in the
<literal>X-Auth-Token</literal> header to perform the
request.</para>
<para>The form &POST; middleware uses the same secret keys as the
temporary URL middleware uses. For information about how to
set these keys, see <xref
linkend="account-secret-keys-temp-url"/>.</para>
<para>For information about the form &POST; middleware
configuration options, see <link
xlink:href="http://docs.openstack.org/havana/config-reference/content/object-storage-form-post.html"
>Form post</link> in the <citetitle>OpenStack
Configuration Reference</citetitle>.</para>
<section xml:id="form-post-format">
<title>Form POST format</title>
<para>To upload objects to a cluster, you can use an HTML form
&POST; request.</para>
<para>The format of the form &POST; request is:</para>
<example xml:id="formpost-example">
<title>Form POST format</title>
<programlistingco>
<areaspec>
<area xml:id="formpost.txt.action"
units="linecolumn" coords="2 26"/>
<area xml:id="formpost.txt.method"
units="linecolumn" coords="3 19"/>
<area xml:id="formpost.txt.enctype"
units="linecolumn" coords="4 36"/>
<area xml:id="formpost.txt.redirect"
units="linecolumn" coords="5 65"/>
<area xml:id="formpost.txt.max_file_size"
units="linecolumn" coords="6 63"/>
<area xml:id="formpost.txt.max_file_count"
units="linecolumn" coords="7 64"/>
<area xml:id="formpost.txt.expires"
units="linecolumn" coords="8 66"/>
<area xml:id="formpost.txt.signature"
units="linecolumn" coords="9 58"/>
<area xml:id="formpost.txt.file"
units="linecolumn" coords="10 39"/>
<area xml:id="formpost.txt.submit"
units="linecolumn" coords="12 28"/>
</areaspec>
<programlisting language="bash"><xi:include href="samples/formpost.txt" parse="text"/></programlisting>
</programlistingco>
</example>
<para>The example shows these attributes:</para>
<calloutlist>
<callout arearefs="formpost.txt.action">
<para><emphasis role="bold"
><literal>action="<replaceable>SWIFT_URL</replaceable>"</literal></emphasis></para>
<para>Set to full URL where the objects are to be
uploaded. The names of uploaded files are appended
to the specified
<replaceable>SWIFT_URL</replaceable>. So, you
can upload directly to the root of a container
with a URL like:</para>
<screen><userinput>https://swift-cluster.example.com/v1/my_account/container/</userinput></screen>
<para>Optionally, you can include an object prefix to
separate uploads, such as:</para>
<screen><userinput>https://swift-cluster.example.com/v1/my_account/container/<replaceable>OBJECT_PREFIX</replaceable></userinput></screen>
</callout>
<callout arearefs="formpost.txt.method">
<para><emphasis role="bold"
>method="POST"</emphasis></para>
<para>Must be <literal>POST</literal>.</para>
</callout>
<callout arearefs="formpost.txt.enctype">
<para><emphasis role="bold"
>enctype="multipart/form-data"</emphasis></para>
<para>Must be
<literal>multipart/form-data</literal>.</para>
</callout>
<callout arearefs="formpost.txt.redirect">
<para><emphasis role="bold">name="redirect"
value="<replaceable>REDIRECT_URL</replaceable>"</emphasis></para>
<para>Redirects the browser to the
<replaceable>REDIRECT_URL</replaceable> after
the upload completes. The URL has status and
message query parameters added to it, which
specify the HTTP status code for the upload and an
optional error message. The
2<replaceable>nn</replaceable> status code
indicates success.</para>
<para>The <replaceable>REDIRECT_URL</replaceable> can
be an empty string. If so, the
<literal>Location</literal> response header is
not set.</para>
</callout>
<callout arearefs="formpost.txt.max_file_size">
<para><emphasis role="bold">name="max_file_size"
value="<replaceable>BYTES</replaceable>"</emphasis></para>
<para>Required. Indicates the size, in bytes, of the
maximum single file upload.</para>
</callout>
<callout arearefs="formpost.txt.max_file_count">
<para><emphasis role="bold">name="max_file_count"
value=
"<replaceable>COUNT</replaceable>"</emphasis></para>
<para>Required. Indicates the maximum number of files
that can be uploaded with the form.</para>
</callout>
<callout arearefs="formpost.txt.expires">
<para><emphasis role="bold">name="expires"
value="<replaceable>UNIX_TIMESTAMP</replaceable>"</emphasis></para>
<para>The UNIX timestamp that specifies the time
before which the form must be submitted before it
becomes no longer valid.</para>
</callout>
<callout arearefs="formpost.txt.signature">
<para><emphasis role="bold">name="signature"
value="<replaceable>HMAC</replaceable>"</emphasis></para>
<para>The HMAC-SHA1 signature of the form. See <xref
linkend="signature-form-post"/>.</para>
</callout>
<callout arearefs="formpost.txt.file">
<para><emphasis role="bold">type="file"
name="<replaceable>FILE_NAME</replaceable>"</emphasis></para>
<para>File name of the file to be uploaded. You can
include from one to the
<literal>max_file_count</literal> value of
files.</para>
<para>The file attributes must appear <emphasis
role="italic">after</emphasis> the other
attributes to be processed correctly.</para>
<para>If attributes appear after the file attributes,
they are not sent with the sub-request because all
attributes in the file cannot be parsed on the
server side unless the whole file is read into
memory; the server does not have enough memory to
service these requests. Attributes that follow the
file attributes are ignored.</para>
</callout>
<callout arearefs="formpost.txt.submit">
<para><emphasis role="bold">type=
"submit"</emphasis></para>
<para>Must be <literal>submit</literal>.</para>
</callout>
</calloutlist>
</section>
<section xml:id="signature-form-post">
<title>HMAC-SHA1 signature for form POST</title>
<para>Form &POST; middleware uses an HMAC-SHA1 cryptographic
signature. This signature includes these elements from the
form:</para>
<itemizedlist>
<listitem>
<para>The path. Starting with <literal>/v1/</literal>
onwards and including a container name and,
optionally, an object prefix. In <xref
linkend="signature-example-form-post"/>, the
path is
<literal>/v1/my_account/container/object_prefix</literal>.
Do not URL-encode the path at this stage.</para>
</listitem>
<listitem>
<para>A redirect URL. If there is no redirect URL, use
the empty string.</para>
</listitem>
<listitem>
<para>Maximum file size. In <xref
linkend="signature-example-form-post"/>, the
<literal>max_file_size</literal> is
<literal>104857600</literal> bytes.</para>
</listitem>
<listitem>
<para>The maximum number of objects to upload. In
<xref linkend="signature-example-form-post"/>,
<literal>max_file_count</literal> is
<literal>10</literal>.</para>
</listitem>
<listitem>
<para>Expiry time. In <xref
linkend="signature-example-form-post"/>, the
expiry time is set to <literal>600</literal>
seconds into the future.</para>
</listitem>
<listitem>
<para>The secret key. Set as the
<literal>X-Account-Meta-Temp-URL-Key</literal>
header value.</para>
</listitem>
</itemizedlist>
<para>The following example code generates a signature for use
with form &POST;:</para>
<example xml:id="signature-example-form-post">
<title>HMAC-SHA1 signature for form POST</title>
<programlisting language="python">import hmac
from hashlib import sha1
from time import time
path = '/v1/my_account/container/object_prefix'
redirect = 'https://myserver.com/some-page'
max_file_size = 104857600
max_file_count = 10
expires = int(time() + 600)
key = '<replaceable>MYKEY</replaceable>'
hmac_body = '%s\n%s\n%s\n%s\n%s' % (path, redirect,
max_file_size, max_file_count, expires)
signature = hmac.new(key, hmac_body, sha1).hexdigest()</programlisting>
</example>
<para>For more information, see <link
xlink:href="http://www.ietf.org/rfc/rfc2104.txt">RFC
2104: HMAC: Keyed-Hashing for Message
Authentication</link>.</para>
</section>
<section xml:id="form-post-curl">
<title>Form POST example</title>
<para>The following example shows how to submit a form by
using a cURL command. In this example, the object prefix
is <literal>photos/</literal> and the file being uploaded
is called <filename>flower.jpg</filename>.</para>
<para>This example uses the
<command>swift-form-signature</command> script to
compute the <literal>expires</literal> and
<literal>signature</literal> values.</para>
<screen><prompt>$</prompt> <userinput>bin/swift-form-signature /v1/my_account/container/photos/ https://example.com/done.html 5373952000 1 200 <replaceable>MYKEY</replaceable>
Expires: 1390825338
Signature: 35129416ebda2f1a21b3c2b8939850dfc63d8f43</userinput></screen>
<screen><prompt>$</prompt> <userinput>curl -i https://swift-cluster.example.com/v1/my_account/container/photos/ -X POST \
-F max_file_size=5373952000 -F max_file_count=1 -F expires=1390825338 \
-F signature=35129416ebda2f1a21b3c2b8939850dfc63d8f43 \
-F redirect=https://example.com/done.html \
-F file=@flower.jpg</userinput></screen>
</section>
</section>

View File

@ -0,0 +1,217 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE section [
<!-- Useful for describing APIs -->
<!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>'>
]>
<section xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:m="http://www.w3.org/1998/Math/MathML"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:db="http://docbook.org/ns/docbook" version="5.0"
xml:id="object-storage-tempurl">
<?dbhtml stop-chunking?>
<title>Temporary URL middleware</title>
<para>A temporary URL gives users temporary access to objects. For
example, a website might want to provide a link to download a
large object in Object Storage, but the Object Storage account
has no public access. The website can generate a URL that
provides time-limited &GET; access to the object. When the web
browser user clicks on the link, the browser downloads the
object directly from Object Storage, eliminating the need for
the website to act as a proxy for the request.</para>
<para>Ask your cloud administrator to enable the temporary URL
feature. For information, see <link
xlink:href="http://docs.openstack.org/havana/config-reference/content/object-storage-tempurl.html"
>Temporary URL</link> in the <citetitle>OpenStack
Configuration Reference</citetitle>.</para>
<note>
<para>To use &POST; requests to upload objects to specific
Object Storage locations, use form &POST; instead of
temporary URL middleware. See <xref linkend="form-post"
/>.</para>
</note>
<section xml:id="temp-url-format">
<title>Temporary URL format</title>
<para>A temporary URL is comprised of the URL for an object
with added query parameters:</para>
<example xml:id="tempurl-example">
<title>Temporary URL format</title>
<programlistingco>
<areaspec>
<area xml:id="tempurl.txt.object_url"
units="linecolumn" coords="1 66"/>
<area xml:id="tempurl.txt.temp_url_sig"
units="linecolumn" coords="2 56"/>
<area xml:id="tempurl.txt.temp_url_expires"
units="linecolumn" coords="3 31"/>
<area xml:id="tempurl.txt.filename"
units="linecolumn" coords="4 28"/>
</areaspec>
<programlisting language="bash"><xi:include href="samples/tempurl.txt" parse="text"/></programlisting>
</programlistingco>
</example>
<para>The example shows
these elements:</para>
<calloutlist>
<callout arearefs="tempurl.txt.object_url">
<para><emphasis role="bold">Object
URL</emphasis></para>
<para>Required. The full path URL to the
object.</para>
</callout>
<callout arearefs="tempurl.txt.temp_url_sig">
<para><emphasis role="bold"
>temp_url_sig</emphasis></para>
<para>Required. An HMAC-SHA1 cryptographic signature
that defines the allowed HTTP method, expiration
date, full path to the object, and the secret key
for the temporary URL.</para>
<para>For more information about secret keys, see
<xref linkend="account-secret-keys-temp-url"
/>.</para>
<para>For more information about signatures, see <xref
linkend="signature-temp-url"/>.</para>
</callout>
<callout arearefs="tempurl.txt.temp_url_expires">
<para><emphasis role="bold"
>temp_url_expires</emphasis></para>
<para>Required. An expiration date as a UNIX Epoch
timestamp, which is an integer value. For example,
<literal>1390852007</literal> represents
<literal>Mon, 27 Jan 2014 19:46:47
GMT</literal>.</para>
<para>For more information, see <link
xlink:href="http://www.epochconverter.com/"
>Epoch &amp; Unix Timestamp Conversion
Tools</link>.</para>
</callout>
<callout arearefs="tempurl.txt.temp_url_expires">
<para><emphasis role="bold">filename</emphasis></para>
<para>Optional. Overrides the default file name.
Object Storage generates a default file name for
&GET; temporary URLs that is based on the object
name. Object Storage returns this value in the
<literal>Content-Disposition</literal>
response header. Browsers can interpret this file
name value as a file attachment to be
saved.</para>
</callout>
</calloutlist>
</section>
<section xml:id="account-secret-keys-temp-url">
<title>Account secret keys</title>
<para>Object Storage supports up to two secret keys. You set
secret keys at the account level.</para>
<para>To set these keys, set one or both of the following
request headers to arbitrary values:</para>
<itemizedlist>
<listitem>
<para><literal>X-Account-Meta-Temp-URL-Key</literal></para>
</listitem>
<listitem>
<para><literal>X-Account-Meta-Temp-URL-Key-2</literal></para>
</listitem>
</itemizedlist>
<para>The arbitrary values serve as the secret keys.</para>
<para>Object Storage checks signatures against both keys, if
present, to enable key rotation without invalidating
existing temporary URLs.</para>
<para>For example, use the <command>swift post</command>
command to set the secret key to
<replaceable>MYKEY</replaceable>:</para>
<screen><prompt>$</prompt> <userinput>swift post -m "X-Account-Meta-Temp-URL-Key: <replaceable>MYKEY</replaceable>"</userinput></screen>
<note>
<para>Changing these headers invalidates any previously
generated temporary URLs within 60 seconds, which is
the memcache time for the key.</para>
</note>
</section>
<section xml:id="signature-temp-url">
<title>HMAC-SHA1 signature for temporary URLs</title>
<para>Temporary URL middleware uses an HMAC-SHA1 cryptographic
signature. This signature includes
these elements:</para>
<itemizedlist>
<listitem>
<para>The allowed method. Typically, &GET; or
&PUT;.</para>
</listitem>
<listitem>
<para>Expiry time. In <xref
linkend="signature-example-temporary-urls"/>,
the expiry time is set to <literal>86400</literal>
seconds (or 1 day) into the future.</para>
</listitem>
<listitem>
<para>The path. Starting with <literal>/v1/</literal>
onwards and including a container name and object.
In <xref
linkend="signature-example-temporary-urls"/>,
the path is
<literal>/v1/my_account/container/object</literal>.
Do not URL-encode the path at this stage.</para>
</listitem>
<listitem>
<para>The secret key. Set as the
<literal>X-Account-Meta-Temp-URL-Key</literal>
header value.</para>
</listitem>
</itemizedlist>
<para>This sample Python code shows how to compute a signature
for use with temporary URLs:</para>
<example xml:id="signature-example-temporary-urls">
<title>HMAC-SHA1 signature for temporary URLs</title>
<programlisting language="python">import hmac
from hashlib import sha1
from time import time
method = 'GET'
duration_in_seconds = 60*60*24
expires = int(time() + duration_in_seconds)
path = '/v1/my_account/container/object'
key = '<replaceable>MYKEY</replaceable>'
hmac_body = '%s\n%s\n%s' % (method, expires, path)
signature = hmac.new(key, hmac_body, sha1).hexdigest()</programlisting>
</example>
<para>Do not URL-encode the path when you generate the
HMAC-SHA1 signature. However, when you make the actual
HTTP request, you should properly URL-encode the
URL.</para>
<para>The <replaceable>MYKEY</replaceable> value is the value
you set in the
<literal>X-Account-Meta-Temp-URL-Key</literal> request
header on the account.</para>
<para>For more information, see <link
xlink:href="http://www.ietf.org/rfc/rfc2104.txt">RFC
2104: HMAC: Keyed-Hashing for Message
Authentication</link>.</para>
</section>
<section xml:id="swift-temp-url-script">
<title>swift-temp-url script</title>
<para>Object Storage provides the
<command>swift-temp-url</command> script that
auto-generates the <parameter>temp_url_sig</parameter> and
<parameter>temp_url_expires</parameter> query
parameters. For example, you might run this
command:</para>
<screen><prompt>$</prompt> <userinput>bin/swift-temp-url GET 3600 /v1/my_account/container/object <replaceable>MYKEY</replaceable></userinput></screen>
<para>This command returns the path:</para>
<screen><computeroutput>/v1/my_account/container/object
?temp_url_sig=5c4cc8886f36a9d0919d708ade98bf0cc71c9e91
&amp;temp_url_expires=1374497657</computeroutput></screen>
<para>To create the temporary URL, prefix this path with the
Object Storage storage host name. For example, prefix the
path with
<literal>https://swift-cluster.example.com</literal>,
as follows:</para>
<screen><computeroutput>https://swift-cluster.example.com/v1/my_account/container/object
?temp_url_sig=5c4cc8886f36a9d0919d708ade98bf0cc71c9e91
&amp;temp_url_expires=1374497657</computeroutput></screen>
</section>
</section>