Subject: [Bug 161] EVALUATE_ALL_OF_IF_HEADER

From: [email-masked]
Date: Tue, 7 Feb 2006 13:40:16 -0800

http://ietf.cse.ucsc.edu:8080/bugzilla/show_bug.cgi?id=161

[email-masked] changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Version|-11                         |-12

------- Additional Comments From [email-masked]  2006-02-07 13:40 -------
OK, below is a first attempt to restructe the definition of the If header.
Feedback appreciated.

10.4.  If Header

   The If request header is intended to have similar functionality to
   the If-Match header defined in Section 14.24 of [RFC2616].  However,
   the If header is intended for use with any URI which represents state
   information, referred to as a state token, about a resource as well
   as ETags.  A typical example of a state token is a lock token, and
   lock tokens are the only state tokens defined in this specification.

10.4.1.  Purpose

   The If header has two distinct purposes:

   o  The first purpose is to make a request conditional by supplying a
      series of state lists.  If the state of the resource to which the
      header is applied does not match any of the specified state lists
      then the request MUST fail with a 412 (Precondition Failed)
      status.  On the other hand, if one of the described state lists
      does match the state of the resource then the request may succeed.
      The matching functions for ETags and state tokens are defined in
      Section 10.4.4 below.

   o  Additionally, the mere fact that a state token appears in an If
      header means that is has been "submitted" with the request.  In
      general, this is used to indicate that the client has knowledge of
      that state token.  The meaning of submitting a state token depends
      on its type (for lock tokens, please refer to Section 6).

   Note that these two purposes need to be treated distinctly: a state
   token counts as being submitted independantly of whether the server
   actually has evaluated the state list it appears in, and also
   independantly of whether the condition it expressed found to be true
   or not.

10.4.2.  Syntax

      If = "If" ":" ( *No-tag-list | 1*Tagged-list )

      No-tag-list = List
      Tagged-list = Resource 1*List

      List = "(" 1*Condition ")"
      Condition = ["Not"] (State-token | "[" entity-tag "]")
      ; entity-tag: see Section 3.11 of [RFC2616]
      ; No LWS allowed between "[", entity-tag and "]"

      State-token = Coded-URL

      Resource = Coded-Reference
      Coded-Reference = "<" Simple-ref ">"
      ; Simple-ref: see Section 8.2
      ; No LWS allowed in Coded-Reference

   The syntax distinguishes between untagged lists ("No-tag-list") and
   tagged lists ("Tagged-list").  Untagged lists apply to the resource
   identified by the Request-URI, while tagged lists apply to the
   resource identified by the preceding Resource "tag".

   A Resource tag applies to all subsequent Lists, up to the next
   Resource tag. [[anchor61: RFC2518: "The same Resource tag MUST NOT
   appear more than once in a resource production in an If header."
   This seems to be meaningless, because that follows from the
   "Resource" production.  Is this intended to require that there aren't
   multiple Tagged-list productions for the same resource?  That would
   need to be expressed differently, and I'm not sure why there should
   be that restriction.  Feedback appreciated.]]

   Note that the two list types can not be mixed within an If header.
   This is not a functional restriction because the No-tag-list syntax
   is just a shorthand notation for a Tagged-list production with a tag
   referring to the Request-URI.

   Each List consists of one or more Conditions.  Each Condition is
   defined in terms of an entity-tag or state-token, potentially negated
   by the prefix "Not".

10.4.3.  Evaluation

   A Condition that consists of a single entity-tag or state-token
   evaluates to true if the resource matches the described state (where
   the individual matching functions are define below in
   Section 10.4.4).  Prefixing it with "Not" reverses the result of the
   evaluation (thus, the "Not" applies only to the subsequent entity-tag
   or state-token).

   Each List production describes a series of conditions.  The whole
   list evaluates to true if and only if each condition evaluates to
   true (that is, the list represents a logical conjunction of
   Conditions).

   Each No-tag-list and Tagged-list production may contain one or more
   Lists.  They evaluate to true if and only if any of the contained
   lists evaluates to true (that is, if there's more than one List, that
   List sequence represents a logical disjunction of the Lists).

   Finally, the whole If header evaluates to true if and only if at
   least one of the No-tag-list or Tagged-list productions evalute to
   true.  If the header evaluates to false, the server MUST reject the
   request with a 412 (Precondition Failed) status.  Otherwise,
   execution of the request can proceed as if the header wasn't present.

10.4.3.1.  Example: No-tag Production

      If: (<urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2>
             ["I am an ETag"])
          (["I am another ETag"])

   The previous header would require that the resource identified in the
   Request-URI be locked with the specified lock token and be in the
   state identified by the "I am an ETag" ETag or in the state
   identified by the second ETag "I am another ETag".

   To put the matter more plainly one can think of the previous If
   header as expressing the condition below:

     (
       is-locked-with(urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2) AND
       matches-etag("I am an ETag")
     )
     OR
     (
       matches-etag("I am another ETag")
     )

10.4.3.2.  Example: using "Not" with No-tag Production

     If: (Not <urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2>
         <urn:uuid:58f202ac-22cf-11d1-b12d-002035b29092>)

   This If header requires that the resource must not be locked with a
   lock having the lock token
   urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2 and must be locked by a
   lock with the lock token with
   urn:uuid:58f202ac-22cf-11d1-b12d-002035b29092.

10.4.3.3.  Example: causing a Condition to always evaluate to True

   There may be cases where a client wishes to submit state tokens, but
   doesn't want the request to fail just because the state token isn't
   current anymore.  One simple way to do this is to include a Condition
   that is known to always evaluate to true, such as in:

     If: (<urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2>)
         (Not <DAV:no-lock>)

   "DAV:no-lock" is known to never represent a current lock token, as
   lock tokens are assigned by the server, following the uniqueness
   requirements described in Section 6.5, thus in particular exclude
   URIs in the "DAV:" scheme.  Thus, by applying "Not" to a known not to
   be current state token, the Condition always evaluates to true.
   Consequently, the whole If header will always evaluate to true, and
   the lock token urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2 will be
   submitted in any case.

10.4.3.4.  Example: Tagged List If header in COPY

   >>Request

   COPY /resource1 HTTP/1.1
   Host: www.example.com
   Destination: /resource2
   If: </resource1>
         (<urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2>
         [W/"A weak ETag"]) (["strong ETag"])
       </random>
         (["another strong ETag"])

   In this example http://www.example.com/resource1 is being copied to
   http://www.example.com/resource2.  When the method is first applied
   to http://www.example.com/resource1, resource1 must be in the state
   specified by "(<urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2> [W/"A
   weak ETag"]) (["strong ETag"])", that is, it either must be locked
   with a lock token of "urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2"
   and have a weak entity tag W/"A weak ETag" or it must have a strong
   entity tag "strong ETag".

   That is the only success condition since the resource
   http://www.example.com/random never has the method applied to it (the
   only other resource listed in the If header) and
   http://www.example.com/resource2 is not listed in the If header.

10.4.4.  Matching Function

   When performing If header processing, the definition of a matching
   state token or entity tag is as follows:

   Identifying a resource: The resource is identified by the URI along
   with the token, in tagged list production, or by the Request-URI in
   untagged list production.

   Matching entity tag: Where the entity tag matches an entity tag
   associated with the identified resource.  Servers MUST use either the
   weak or the strong comparison function defined in Section 13.3.3 of
   [RFC2616].

   Matching state token: Where there is an exact match between the state
   token in the If header and any state token on the identified
   resource.  A lock state token is considered to match if the resource
   is anywhere in the scope of the lock.

   Example - Matching lock tokens with collection locks

     DELETE /specs/rfc2518.txt HTTP/1.1
     Host: www.example.com
     If: <http://www.example.com/specs/>
         (<urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2>)
   For this example, the lock token must be compared to the identified
   resource, which is the 'specs' collection identified by the URL in
   the tagged list production.  If the 'specs' collection is not locked
   or has a lock with a different token, the request MUST fail.  If the
   'specs' collection is locked (depth infinity) with that lock token,
   then this request could succeed, both because the If header evaluates
   to true, and because the lock token for the lock affecting the
   affected resource has been submitted.  Alternatively, a request where
   the 'rfc2518.txt' URL is associated with the lock token in the If
   header could also succeed.

10.4.5.  If Header and Non-DAV Aware Proxies

   Non-DAV aware proxies will not honor the If header, since they will
   not understand the If header, and HTTP requires non-understood
   headers to be ignored.  When communicating with HTTP/1.1 proxies, the
   "Cache-Control: no-cache" request header MUST be used so as to
   prevent the proxy from improperly trying to service the request from
   its cache.  When dealing with HTTP/1.0 proxies the "Pragma: no-cache"
   request header MUST be used for the same reason.

10.4.6.  If Header and Authentication

   Servers MUST do authorization checks before checking this header
   (thus, supplying a carefully crafted If header must not allow a
   client to learn information about resources it's not authorized to
   access).

------- You are receiving this mail because: -------
You are the QA contact for the bug, or are watching the QA contact.