Conditional operations

Content Platform Tenant Management Help

Version
9.7.x
File Size
4269 KB
Audience
anonymous
Part Number
MK-95HCPH002-19

Conditional operations let you tell HCP to perform an operation only if the current object or specified version meets certain conditions. A conditional operation can use an ETag or a datetime value. HCP compares the value that you provide in the header with the corresponding value for the object or version and performs the requested action only if the specified condition is met.

Here are two typical uses for conditional operations:

  • Managing a local object cache. You can reduce the load on HCP and your network by maintaining a local cache of frequently used objects. When the local application requires an object, it can send a conditional GET request to HCP to retrieve a new version only if the object has changed.
  • Managing storage by multiple users or applications. An application that updates an object can use a conditional PUT request that tells HCP to store the new version only if the ETag of the existing version equals the ETag of the last known version of the object. Otherwise, the application gets an error return, and can handle the data conflict appropriately. This technique can be useful in cases where several users might update the same object.

You can specify conditions in GET, HEAD, and PUT requests for objects and versions. You cannot use them in DELETE requests for these items. Doing so results in an HTTP 400 (Bad Request) error code.

Note: HCP ignores conditional headers in GET, HEAD, and PUT requests for annotations, ACLs, directories, and symbolic links and in POST requests for system metadata. It returns an HTTP 400 (Bad Request) error code in response to a conditional DELETE request for any of these items.

Request headers

You use the headers described in the table below to specify conditional operations.

Header Value Description
If-Match

One of:

  • Comma-separated list of ETag values
  • asterisk (*)

Perform the operation only if the ETag of the object or version is identical to one of the specified ETag values.

For an asterisk, perform the operation if the object exists.

If-None-Match

One of:

  • Comma-separated list of ETag values
  • asterisk (*)

Perform the operation only if the ETag of the object or version is not equal to any of the specified ETag values.

For an asterisk, perform the operation if the object doesn’t exist.

If-Modified-Since Datetime value Perform the operation only if the object or version change time was after the specified time.
If-Unmodified-Since Datetime value Perform the operation only if the object or version change time was at or before the specified time.

When you use the PUT method to copy an object, the headers listed in the table above apply to any existing version of the target object. You can use the headers describe in the table below to specify conditions for the source object.

Header Contents Description
X-HCP-CopySource-If-Match

One of:

  • Comma-separated list of ETag values
  • asterisk (*)

Perform the copy operation only if the ETag of the source object or version is equal to one of the specified ETag values.

For an asterisk, perform the operation if the object exists.

X-HCP-CopySource-If-None-Match

One of:

  • Comma-separated list of ETag values
  • asterisk (*)

Perform the copy operation only if the ETag of the source object or version is not equal to any of the specified ETag values.

For an asterisk, perform the operation if the object does not exist.

X-HCP-CopySource-If-Modified-Since Datetime value Perform the copy operation only if the source object or version change time was after the specified time.
X-HCP-CopySource-If-Unmodified-Since Datetime value Perform the copy operation only if the source object or version change time was at or before the specified time.

A request can specify more than one condition. In such a request:

  • HCP evaluates all the conditions. However, if the request includes both If-None-Match and If-Modified-Since headers, the If-Modified-Since header is ignored.
  • Headers that use ETag values are processed before headers that use datetime values.

ETag values

The list of ETag values used in the If-Match and If-None-Match header has this format:

"ETag-value"[, "ETag-value"]...

Because the individual ETag values are enclosed in double quotation marks ("), in curl and PycURL commands, you need to enclose the entire header in single quotation marks ('), as shown below:

'If-None-Match: "d158a5494cf76bf2cbbe40a7aa674543","638c9bd8d4c2c1022c6fcac9227f5af4"'

In the If-Match and If-None-Match headers, you typically use the ETag values returned in ETag headers of prior requests, such as when you store objects. This way, for example, you can prevent your application from retrieving a version of an object that your application has already cached or from storing an object version that already exists in HCP.

Datetime headers

Datetime headers let you perform operations based on whether an object has been modified since a specific time.

Datetime values for the If-Modified-Since and If-Unmodified-Since headers must be in one of these formats:

  • Format: DDD, dd MMM yyyy hh:mm:ss GMT

    Example: Mon, 01 Jan 2013 15:30:00 GMT

    The Last-Modified header returned by GET and HEAD requests for objects and versions is in this format.

  • Format: Day, dd-MMM-yy hh:mm:ss GMT

    Example: Monday, 01-Jan-13 15:30:00 GMT

  • Format: DDD MMM d hh:mm:ss yyyy

    Example: Mon Jan 1 15:30:00 2013

The following considerations apply to using datetime headers for conditional processing:

  • HCP compares the header value with the object change time. Several events, including system events, cause HCP to update the object change time.
  • Change time resolution is only to the second, so you cannot use these headers to differentiate between changes that happened during the same second.
  • If a header contains an invalid datetime value, HCP ignores the header and does not return an error response.

Handling objects that might not have ETags

If the HCP system has been upgraded from a release earlier than 6.0, some objects that were stored in the namespace before the upgrade may not yet have ETags. In such cases, the HCP behavior depends on the request type and object size, as follows:

  • For a GET request for an object 512,000 bytes or smaller, HCP automatically calculates the ETag, returns it in the ETag header and uses it, if needed, for conditional processing.
  • For a GET request for an object larger than 512,000 bytes, by default, HCP does not calculate the ETag. In this case:
    • The response does not return an ETag header.
    • If the request has an If-Match or If-None-Match header, HCP returns a 400 error response with a message explaining the cause.
  • For a PUT request to copy an object, HCP handles the source object the same way it handles the object in a GET request. For source objects of 512,000 bytes or less, HCP calculates and saves the ETag and uses it to processes any X-HCP-CopySource-If-Match or X-HCP-CopySource-If-None-Match header. For larger source objects, using these headers results in a 400 error response.
  • For a PUT or HEAD request, including for the target of a PUT request to copy an object, HCP does not generate the ETag for an existing object. If a PUT or HEAD request has an If-Match or If-None-Match header and specifies an object that does not yet have an ETag, HCP returns a 400 error.

If you get an error because an object does not have an ETag, you can force HCP to calculate the missing ETag by including a forceEtag query parameter with a value of true in either of these requests:

  • A GET request. In this case, HCP processes any If-Match or If-None-Match header and includes an ETag header when it returns an object.
  • A PUT request to copy an object. In this case, HCP processes any X-HCP-CopySource-If-Match or X-HCP-CopySource-If-None-Match header and can copy the specified object if the condition is met.

Once HCP has generated an object ETag, you can use conditional headers in GET, PUT, and HEAD requests for the object.

Example: Conditionally storing a new version

Here’s a sample HTTP PUT request that stores a new version of an object named Q3_2012.ppt in the quarterly_rpts directory if the current version of the object has not been modified since 9:00 a.m., EST on Monday, November 5, 2012.

Request with curl command line

curl -k -iT Q1_2012.ppt -H "If-Unmodified-Since: Mon, 05 Nov 2012 14:00:00
    GMT" -H "Authorization: HCP bXl1c2Vy:3f3c6784e97531774380db177774ac8d"
    "https://finance.europe.hcp.example.com/rest/quarterly_rpts/Q1_2012.ppt"

Request in Python using PycURL

import pycurl
import os
filehandle = open("Q3_2012.ppt", 'rb')
curl = pycurl.Curl()
curl.setopt(pycurl.HTTPHEADER, ["Authorization: HCP
  bXl1c2Vy:3f3c6784e97531774380db177774ac8d"])
curl.setopt(pycurl.URL, "https://finance.europe.hcp.example.com/ \
  rest/quarterly_rpts/Q3_2012.ppt")
curl.setopt(pycurl.SSL_VERIFYPEER, 0)
curl.setopt(pycurl.SSL_VERIFYHOST, 0)
curl.setopt(pycurl.HTTPHEADER, ["If-Unmodified-Since: Mon, 05 Nov
  2012 14:00:00 GMT"])
curl.setopt(pycurl.UPLOAD, 1)
curl.setopt(pycurl.INFILESIZE, os.path.getsize("Q1_2012.ppt"))
curl.setopt(pycurl.READFUNCTION, filehandle.read)
curl.perform()
print curl.getinfo(pycurl.RESPONSE_CODE)
curl.close()
filehandle.close()

Request headers

PUT /rest/quarterly_rpts/Q1_2012.ppt HTTP/1.1
Host: /finance.europe.hcp.example.com
Authorization: HCP bXl1c2Vy:3f3c6784e97531774380db177774ac8d
If-Unmodified-Since: Mon, 05 Nov 2012 14:00:00
Content-Length: 678400

Response headers

HTTP/1.1 201 Created
X-HCP-ServicedBySystem: hcp.example.com
ETag: 78821a05d282822e4abec190c061ba78
Location: /rest/quarterly_rpts/Q1_2012.ppt
X-HCP-VersionId: 79885459513089
X-HCP-Hash: SHA-256 E830B86212A66A792A79D58BB185EE63A4FADA76BB8A1...
X-HCP-Time: 1358245832
Content-Length: 0

Example: Conditionally retrieving all object data

Here’s a sample HTTP GET request that retrieves an object named

Q1_2012.ppt in the quarterly_rpts directory if the ETag of the object data does not match the ETag of version of the object that was previously retrieved from HCP. This technique prevents downloading a copy of an object that’s already available.

Request with curl command line

curl -k -H "Authorization: HCP bXl1c2Vy:3f3c6784e97531774380db177774ac8d"
    -H 'If-None-Match: "d158a5494cf76bf2cbbe40a7aa674543"'
    "https://finance.europe.hcp.example.com/rest/quarterly_rpts/Q1_2012.ppt" >
    Q1_2012.ppt

Request in Python using PycURL

import pycurl
filehandle = open("Q1_2012.ppt", 'wb')
curl = pycurl.Curl()
curl.setopt(pycurl.HTTPHEADER, ["Authorization: HCP
  bXl1c2Vy:3f3c6784e97531774380db177774ac8d", "If-None-Match:
  d158a5494cf76bf2cbbe40a7aa674543"])
curl.setopt(pycurl.URL, "https://finance.europe.hcp.example.com \
  /rest/quarterly_rpts/Q1_2012.ppt")
curl.setopt(pycurl.SSL_VERIFYPEER, 0)
curl.setopt(pycurl.SSL_VERIFYHOST, 0)
curl.setopt(pycurl.WRITEFUNCTION, filehandle.write)
curl.perform()
print curl.getinfo(pycurl.RESPONSE_CODE)
curl.close()
filehandle.close()

Request headers

GET /rest/quarterly_rpts/Q1_2012.ppt HTTP/1.1
Host: finance.europe.hcp.example.com
Authorization: HCP bXl1c2Vy:3f3c6784e97531774380db177774ac8d
If-None-Match: d158a5494cf76bf2cbbe40a7aa674543

Response headers

HTTP/1.1 200 OK
X-HCP-ServicedBySystem: hcp.example.com
X-HCP-Time: 1353352625
X-HCP-SoftwareVersion: 7.0.0.16
ETag: "d45e5b124c1807d6ec4f8088b5e51f8d"
Content-Type: application/vnd.ms-powerpoint
Content-Length: 130919
X-HCP-Type: object
X-HCP-Size: 130919
X-HCP-Hash: SHA-256 F19D0CA6D684F4B9C48789828A31551A50673597ABAC66C6D7....
X-HCP-VersionId: 86614553936513
X-HCP-IngestTime: 1353352405
X-HCP-RetentionClass:
X-HCP-RetentionString: Deletion Allowed
X-HCP-Retention: 0
X-HCP-IngestProtocol: HTTP
X-HCP-RetentionHold: false
X-HCP-Shred: false
X-HCP-DPL: 2
X-HCP-Index: true
X-HCP-Custom-Metadata: false
X-HCP-ACL: false
X-HCP-Owner: europe
X-HCP-Domain:
X-HCP-UID:
X-HCP-GID:
X-HCP-Replicated: false
X-HCP-ReplicationCollision: false
X-HCP-ChangeTimeMilliseconds: 1353352405323.00
X-HCP-ChangeTimeString: 2012-11-19T14:13:25-0500
Last-Modified: Mon, Nov 19 2012 19:13:25 GMT

Response body: The contents of the Q1_2012.ppt object