|
| 1 | +## Conditional Requests |
| 2 | + |
| 3 | +The [Distribution Specification](spec.md) describes mutable tag identifiers, which can be used when pushing, pulling, and deleting manifests. |
| 4 | +Given that HTTP is a stateless protocol for distributed systems, the mutability of tag references leads to many possible race conditions. |
| 5 | +Fortunately, HTTP has a mechanism for dealing with race conditions: conditional requests. |
| 6 | + |
| 7 | +[RFC 7232](https://tools.ietf.org/html/rfc7232) defines the semantics of Conditional Requests in great detail, so this document will simply highlight the relevant portions of the RFC as applied to the Distribution Specification. |
| 8 | + |
| 9 | +### Safely Mutating Manifests |
| 10 | + |
| 11 | +The `If-Match` header from [section 3.1](https://tools.ietf.org/html/rfc7232#section-3.1): |
| 12 | + |
| 13 | +> makes the request method conditional on |
| 14 | +> the recipient origin server either having at least one current |
| 15 | +> representation of the target resource, when the field-value is "\*", |
| 16 | +> or having a current representation of the target resource that has an |
| 17 | +> entity-tag matching a member of the list of entity-tags provided in |
| 18 | +> the field-value. |
| 19 | +
|
| 20 | +Specifically interesting for mutating manifests: |
| 21 | + |
| 22 | +> If-Match is most often used with state-changing methods (e.g., POST, |
| 23 | +> PUT, DELETE) to prevent accidental overwrites when multiple user |
| 24 | +> agents might be acting in parallel on the same resource (i.e., to |
| 25 | +> prevent the "lost update" problem). It can also be used with safe |
| 26 | +> methods to abort a request if the selected representation does not |
| 27 | +> match one already stored (or partially stored) from a prior request. |
| 28 | +
|
| 29 | +A client wishing to safely mutate a manifest SHOULD include in the manifest PUT request the following header: |
| 30 | + |
| 31 | +``` |
| 32 | +If-Match: "<ETag>" |
| 33 | +``` |
| 34 | + |
| 35 | +Where `<ETag>` is the entity-tag that matches the representation of the manifest as expected by the client, i.e. the header returned by the registry, as described in [section 2.3](https://tools.ietf.org/html/rfc7232#section-2.3): |
| 36 | + |
| 37 | +> The "ETag" header field in a response provides the current entity-tag |
| 38 | +> for the selected representation, as determined at the conclusion of |
| 39 | +> handling the request. An entity-tag is an opaque validator for |
| 40 | +> differentiating between multiple representations of the same |
| 41 | +> resource, regardless of whether those multiple representations are |
| 42 | +> due to resource state changes over time, content negotiation |
| 43 | +> resulting in multiple representations being valid at the same time, |
| 44 | +> or both. An entity-tag consists of an opaque quoted string, possibly |
| 45 | +> prefixed by a weakness indicator. |
| 46 | +
|
| 47 | +If the state of the manifest in the registry does not match the supplied ETag, the registry MUST return a `412 Precondition Failed` response. |
| 48 | + |
| 49 | +### Avoiding Overwriting Tags |
| 50 | + |
| 51 | +The `If-None-Match` header from [section 3.2](https://tools.ietf.org/html/rfc7232#section-3.2): |
| 52 | + |
| 53 | +> makes the request method conditional |
| 54 | +> on a recipient cache or origin server either not having any current |
| 55 | +> representation of the target resource, when the field-value is "\*", |
| 56 | +> or having a selected representation with an entity-tag that does not |
| 57 | +> match any of those listed in the field-value |
| 58 | +
|
| 59 | +Specifically interesting for avoiding tag overwriting: |
| 60 | + |
| 61 | +> If-None-Match can also be used with a value of "\*" to prevent an |
| 62 | +> unsafe request method (e.g., PUT) from inadvertently modifying an |
| 63 | +> existing representation of the target resource when the client |
| 64 | +> believes that the resource does not have a current representation |
| 65 | +> (Section 4.2.1 of [RFC7231]). This is a variation on the "lost |
| 66 | +> update" problem that might arise if more than one client attempts to |
| 67 | +> create an initial representation for the target resource. |
| 68 | +
|
| 69 | +A client wishing to avoid overwriting any existing tags SHOULD include in the manifest PUT request the following header: |
| 70 | + |
| 71 | +``` |
| 72 | +If-None-Match: * |
| 73 | +``` |
| 74 | + |
| 75 | +If there already exists a manifest in the registry with a matching tag identifier, the registry MUST return a `412 Precondition Failed` response. |
0 commit comments