COPY'> GET'> HEAD'> PUT'> POST'> DELETE'> ]>
Storage Object Services 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. Verb URI Description &GET; /account/container/object Gets object details. &PUT; /account/container/object Creates or updates object. &PUT; /account/container/object Chunked transfer encoding. &DELETE; /account/container/object Deletes a specified object. &HEAD; /account/container/object Gets object metadata. &POST; /account/container/object Updates object metadata. Optional headers for HEAD and GET X-Newest Set the optional X-newest header to True in HEAD and GET requests to have Object Storage return the latest version of the object. If set to True, Object Storage queries all replicas to return the most recent one. Without this header, Object Storage responds faster after it finds one valid replica. Because setting this header to True is more expensive for the back end, use it only when it is absolutely needed.
Get Object Details Perform &GET; operations against an object to get object data. You can perform conditional &GET; requests by using the following HTTP headers in the request: If-Match If-None-Match If-Modified-Since If-Unmodified-Since These headers are documented in http://www.ietf.org/rfc/rfc2616.txt. You can use the HTTP Range header to fetch portions of data by using one or more range specifications. To specify many ranges, separate the range specifications with a comma. The types of range specifications are: Byte range specification. 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. Suffix byte range specification. Use LENGTH bytes to specify the length of the data range. The following forms of the header specify the following ranges of data: Header Range of object data Range: bytes=-5 The last five bytes. Range: bytes=10-14 The five bytes of data after a 10-byte offset. Range: bytes=10-14,-5 A multi-part response that contains the five bytes of data after a 10-byte offset and the last five bytes. The Content-Type of the response is then multipart/byteranges. Range: bytes=4-6 Bytes 4 to 6 inclusive. Range: bytes=2-2 Byte 2, which is the third byte of the data. Range: bytes=6- Byte 6 and after. Range: bytes=1-3,2-5 A multi-part response that contains bytes 1 to 3 inclusive, and bytes 2 to 5 inclusive. The Content-Type of the response is then multipart/byteranges. Get Object Details HTTP Request The object 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. Get Object Details HTTP Response These examples include an object that contains 10 bytes of data: 0123456789. Get Object Details HTTP Request Using Range Get Object Details HTTP Response When Using Range Get Object Details HTTP Request Using Multiple Ranges Get Object Details HTTP Response When Using Multiple Ranges
Create or Update Object &PUT; operations are used to write, or overwrite, an object's content and metadata. 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. You can cause an object to expire after a certain date by using the X-Delete-At or X-Delete-After 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. 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 manifest objects, the ETag is the MD5 checksum of the concatenated string of ETags for each of the segments in the manifest. Refer to Create Large Objects for more information. Objects can be assigned custom metadata by including additional HTTP headers on the &PUT; request. The object can be created with custom metadata via HTTP headers identified with the X-Object-Meta- prefix, or arbitrary headers set with the allowed_headers option in the object-server configuration. Create or Update Object HTTP Request [ ... ] No response body is returned. A status code of 201 (Created) indicates a successful write; status 411 (Length Required) denotes a missing Content-Length or Content-Type header in the request. If the MD5 checksum of the data written to the storage system does NOT match the (optionally) supplied ETag value, a 422 (Unprocessable Entity) response is returned. Create or Update Object HTTP Response
Chunked Transfer Encoding 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 Transfer-Encoding: chunked and not using a Content-Length 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 see . Upload Unspecified Quantity of Content HTTP Request Upload Unspecified Quantity of Content HTTP Response
Create Large Objects The content of an object cannot be larger than 5GB (by default). However, you can store larger content using two types of objects: Divide your content into pieces and upload each piece into its own object. These objects are known as segment objects. Create a manifest object. A manifest object "points to" the segment objects. Segment objects do not have any special features and can be created, updated, downloaded and deleted as described elsewhere in this document. However, a manifest object is special -- when you download, the system concatenates the contents of the segment objects and returns this in the response body of the request. This behavior extends to the response headers returned by &GET; and &HEAD; operations. The Content-Length is the total size of all segment objects and the ETag is calculated by taking the ETag value of each segment, concatenating them together and then returning the MD5 checksum of the result. 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 5 GB, the © operation fails. However, as explained later, you can make a duplicate of the manifest object. This new object can be larger than 5 GB. The manifest object type are: Static large objects. The manifest object content is an ordered list of the names of the segment objects in json format. Dynamic large objects. The manifest object has no content. However, it has X-Object-Manifest metadata. The value of this is <container>/<prefix>, where <container> is the name of the container where the segment objects are stored and <prefix> is a string that all the segment objects have in common. While both types of manifest objects have similar behavior, there are differences as explained in the following table.
Comparison of Static and Dynamic Large Objects
Feature Static Large Object Dynamic Large Object
End-to-end integrity Assured. The list of segments includes the MD5 checksum (ETag) of each segment. You cannot upload the manifest object if the ETag in the list differs from the segment object already uploaded. If a segment is somehow lost, an attempt to download the manifest object will result in an error. Not guaranteed. The eventual consistency model means that although you may have uploaded a segment object, it may not appear in the container listing until later. If you download the manifest before it appears in the container, it will not form part of the content returned in response to a &GET; request.
Upload order The segment objects must be uploaded before the manifest object. You can upload manifest and segment objects in any order. You are recommended to upload the manifest object after the segments in case a premature download of the manifest occurs. However, this is not enforced.
Removal or addition of segment objects You cannot add or remove segment objects from the manifest. However, you can create a completely new manifest object of the same name with a different manifest list. You can upload new segment objects or remove existing segments --- the names must simply match the <prefix> supplied in X-Object-Manifest.
Segment object size and number Segment objects must be at least 1MB in size (by default). The final segment object can be any size. At most 1000 segments are supported (by default). Segment objects can be of any size.
Segment object container name The manifest list includes the container name of each object, i.e., segment objects may be in different containers. All segment objects must be in the same container
Manifest Object Metadata The object has X-Static-Large-Object set to true. You do not set this metadata directly. Instead the system sets it when you &PUT; a static manifest object. The X-Object-Manifest value is the <container>/<prefix> indicating where the segment objects are located. You supply this request header in the &PUT; operation
Making a copy of the manifest object To make a copy of the manifest object, include the ?multipart-manifest=get query string with the © operation. The new object contains the same manifest as the original. The segment objects are not copied. Instead, both the original and new manifest objects share the same set of segment objects. The © operation does not create a manifest object. To duplicate a manifest object, use the &GET; operation to read the value of X-Object-Manifest and use this value in the X-Object-Manifest request header in a &PUT; operation. This creates a new manifest object that shares the same set of segment objects as the original manifest object.
Dynamic Large Objects 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 dynamic large 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. 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. 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. Upload Segment of Large Object HTTP Request Upload Segment of Large Object HTTP Response s 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 Content-Length or Content-Type header in the request. If the MD5 checksum of the data written to the storage system does NOT match the (optionally) supplied ETag value, a 422 (Unprocessable Entity) response is returned. You can continue uploading segments like this example shows, prior to uploading the manifest. Upload Next Segment of Large Object HTTP Request Upload Next Segment of Large Object HTTP Response w 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. Upload Manifest HTTP Request Upload Manifest HTTP Response 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.
Static Large Objects To create a static large object: Divide your content into pieces and create (upload) a segment object to contain each piece. You must record the ETag response header returned by the&PUT; operation. Alternatively, you can calculate the MD5 checksum of the segment prior to uploading and include this in the ETag request header. This ensures that the upload cannot corrupt your data. List the name of each segment object along with its size and MD5 checksum in order. Create a manifest object. You indicate that this is a manifest object by including the ?multipart-manifest=put query string at the end of the manifest object name. The body of the &PUT; request on the manifest object comprises a json list, where each element contains the following: path - this is the container and object name in the following format: <container-name>/<object-name> etag - this is the MD5 checksum of the content of the segment object. This must match the ETag of that object. size_bytes - this is the size of the segment object. This must match the Content-Length of that object Static Large Object Manifest List This is an example containing three segment 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. The Content-Length request header must contain the length of the json content -- not the length of the segment objects. However, after the &PUT; operation completes, the Content-Length metadata is set to the total length of all the object segments. A similar situation applies to the ETag. If used in the &PUT; operation, it must contain the MD5 checksum of the json content. The ETag metadata value is then set to be the MD5 checksum of the concatenated ETag values of the object segments. You may also set the Content-Type request header and custom object metadata. When the &PUT; operation sees the ?multipart-manifest=put query string, it reads the request body and verifies that each segment object exists and that the sizes and ETags match. If there is a mismatch, the &PUT;operation will fail. If everything matches, the manifest object is created. The X-Static-Large-Object metadata is set to true indicating that this is a static object manifest. Normally when you perform a &GET; operation on the manifest object, the response body contains the concatenated content of the segment objects. To download the manifest list, use the query string ?multipart-manifest=get. The resulting list will not be identically formatted as the manifest you originally used in the &PUT; operation. If you use the &DELETE; operation on a manifest object, the manifest object is deleted -- the segment objects are not affected. However, if you add the query parameter ?multipart-manifest=delete, the segment objects are deleted and if all are successfully deleted, the manifest object is also deleted. To change the manifest, use a &PUT; operation with the ?multipart-manifest=put query string. This will create a new manifest object. You may also update the object metadata in the usual way.
Assign CORS headers to requests 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 www.w3.org/TR/access-control/.
Supported Headers
Metadata Use
X-Container-Meta-Access-Control-Allow-Origin Origins to be allowed to make Cross Origin Requests, space separated.
X-Container-Meta-Access-Control-Max-Age Max age for the Origin to hold the preflight results.
X-Container-Meta-Access-Control-Expose-Headers Headers exposed to the user agent (e.g. browser) in the the actual request response. Space separated.
CORS metadata is held on the container only. The values given apply to the container itself and all objects within it. Assign CORS header request: HTTP 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: You can find more details in the Swift Documentation.
Enabling File Compression with the Content-Encoding Header 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. Content-Encoding Header HTTP Request In the example, the content-encoding header is assigned with an attachment type that indicates how the file should be downloaded:
Enabling Browser Bypass with the Content-Disposition Header 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. Content-Disposition Header HTTP Request In the example, the content-encoding header is assigned with an attachment type that indicates how the file should be downloaded.
Expiring Objects with the X-Delete-After and X-Delete-At Headers When an object is assigned either an X-Delete-After or X-Delete-At 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. The X-Delete-At header requires a Unix Epoch timestamp, in integer form; for example: 1348691905 represents Wed, 26 Sep 2012 20:38:25 GMT. 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. The X-Delete-After 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 X-Delete-At header and calculates the deletion time using its current time plus the value given in seconds. For existing objects that you want to assign expiration headers to, use the &POST; operation. Delete Object at HTTP Request In the example, the X-Delete-At header is assigned with a Unix Epoch timestamp in integer form for Mon, 11 Jun 2012 15:38:25 GMT. Use http://www.epochconverter.com/ for example timestamps and a batch converter. Delete Object after HTTP Request In this example, the X-Delete-After header is assigned a value in seconds, equivalent to 10 days. After this time, the object expires.
Object Versioning 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), &PUT;s 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. To enable object versioning, your cloud provider has to set allow_versions to TRUE in their container config. Then, create a container where your non-current versions will be written. Next, set the metadata X-Versions-Location 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 X-Versions-Location 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. 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. Naming Schema: Non-current versions are assigned the name <length><object_name>/<timestamp>, where 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. 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 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. A &GET; to a versioned object returns the current version of the object without having to do any request redirects or metadata lookups. 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. 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. A large-object manifest file cannot be versioned, but it may point to versioned segments. To turn off Object Versioning on your current version container, remove its X-Versions-Location metadata by sending an empty key value. Object Versioning with cURL Make sure a version-storing container exists, creating it if necessary (this example names it "versions"). Then create a container with the X-Versions-Location header. In this example, this container is named "current". You can also add the X-Versions-Location 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". Create a container named versions. $ curl -i -XPUT -H "X-Auth-Token: <token>" http://<storage_url>/versions Create a container named current with the X-Versions-Location header that references "versions". $ curl -i -XPUT -H "X-Auth-Token: <token>" \ -H "X-Versions-Location: versions" http://<storage_url>/current Create an object (the first version): $ curl -i -XPUT --data-binary 1 -H "X-Auth-Token: <token>" \ http://<storage_url>/current/myobject Now create a new version of that object: $ curl -i -XPUT --data-binary 2 -H "X-Auth-Token: <token>" \ http://<storage_url>/current/myobject See a listing of the older versions of the object: $ curl -i -H "X-Auth-Token: <token>" \ http://<storage_url>/versions?prefix=008myobject/ Now delete the current version of the object and see that the older version is gone: $ 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/
Copy Object 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. 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 “X-Copy-From” 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 X-Copy-From &PUT; requests require a Content-Length header, even if it is zero (0). Object Copy Method 1 The second way to do an object copy is similar. Do a © 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”. Object Copy Method 2 With both of these methods, the destination container must exist before attempting the copy. If the source object is a manifest object, i.e., an object with X-Object-Manifest or X-Static-Large-Object:true metadata, the copy operation concatenates the segment objects when making the content for the destination object. You cannot copy an object larger than 5GB (by default). Refer to Large Object Creation for more information about large objects. However, for a Static Large Object manifest, it is possible to copy the manifest so that the destination becomes a manifest object. Use the ?multipart-manifest=get query string to indicate that you want a copy of the manifest object. The new object will contain the same manifest as the original. The segment objects are not copied. Instead, both the original and new manifest objects share the same set of segment objects. 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 © + &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 ©) 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.
Delete Object &DELETE; operations on an object are used to permanently remove an object from the storage system (metadata and data). 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. For static large object manifests, you can add the query parameter ?multipart-manifest=delete. The segment objects are deleted and if all are successfully deleted, the manifest object is also deleted. Objects with the X-Delete-At or X-Delete-After header assigned are deleted within one day of the expiration time and the object is not served immediately after the expiration time. Refer to Expiring Objects for more details. Object Delete HTTP Request 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 exist. Object Delete HTTP Response
Get Object Metadata &HEAD; operations on an object are used to retrieve object metadata and other standard HTTP headers. The only required header to be sent in the request is the authorization token. Get Object Metadata HTTP Request 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. Get Object Metadata HTTP Response
Update Object Metadata &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 X-Delete-At or X-Delete-After for expiring objects. You cannot use the &POST; operation to change any of the object's other headers such as Content-Type, ETag, etc. It is not used to upload storage objects (see &PUT;). Also refer to copying an object when you need to update metadata or other headers such as Content-Type or CORS headers. Key names must be prefixed with X-Object-Meta-. A &POST; request will delete all existing metadata added with a previous &PUT;/&POST;. Update Object Metadata HTTP Request 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. Update Object Metadata HTTP Response