Ignore:
Timestamp:
Apr 5, 2011, 3:49:27 PM (9 years ago)
Author:
fielding@…
Message:

editorial: rearrange p4 a bit more to split discussion of last-modified
from that of entity-tags, move entity-tags definition within the ETag
header field, and introduce sections for requirements on generation
and comparison of each (separately). This roughly halves the
cognitive complexity of the existing descriptions and allows us
to get rid of a lot of duplication (with more to come).

Moved some stray requirements on range requests to p5.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • draft-ietf-httpbis/latest/p4-conditional.xml

    r1254 r1260  
    221221   specify preconditions to be checked before performing the action
    222222   given by the request method.  Conditional GET requests are the most
    223    efficient mechanism for HTTP cache updates &caching;.  Conditionals can be
     223   efficient mechanism for HTTP cache updates &caching;.  Conditionals
     224   can also be
    224225   applied to state-changing methods, such as PUT and DELETE, to prevent
    225226   the "lost update" problem: one client accidentally overwriting
     
    313314   has been defined by various extensions of HTTP, such as WebDAV
    314315   <xref target="RFC4918"/>, that are beyond the scope of this specification.
    315    Such metadata is referred to as a "<x:dfn>validator</x:dfn>" when it is
    316    used within a precondition.
     316   A resource metadata value is referred to as a "<x:dfn>validator</x:dfn>"
     317   when it is used within a precondition.
    317318</t>
    318319
     
    323324<t>
    324325   The "Last-Modified" header field indicates the date and time at
    325    which the origin server believes the representation was last modified.
     326   which the origin server believes the selected representation was
     327   last modified.
    326328</t>
    327329<figure><artwork type="abnf2616"><iref primary="true" item="Grammar" subitem="Last-Modified"/>
     
    334336  Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT
    335337</artwork></figure>
     338
     339<section title="Generation" anchor="lastmod.generation">
     340<t>
     341   Origin servers &SHOULD; send Last-Modified for any selected
     342   representation for which a last modification date can be reasonably
     343   and consistently determined, since its use in conditional requests
     344   and evaluating cache freshness (&caching;) results in a substantial
     345   reduction of HTTP traffic on the Internet and can be a significant
     346   factor in improving service scalability and reliability.
     347</t>
    336348<t>
    337349   A representation is typically the sum of many parts behind the
     
    345357</t>
    346358<t>
    347    An origin server &MUST-NOT; send a Last-Modified date which is later
    348    than the server's time of message origination. In such cases, where
    349    the resource's last modification would indicate some time in the
    350    future, the server &MUST; replace that date with the message
    351    origination date.
    352 </t>
    353 <t>
    354    An origin server &SHOULD; obtain the Last-Modified value of the representation
    355    as close as possible to the time that it generates the Date value of
    356    its response. This allows a recipient to make an accurate assessment
    357    of the representation's modification time, especially if the representation changes
    358    near the time that the response is generated.
    359 </t>
    360 <t>
    361    HTTP/1.1 servers &SHOULD; send Last-Modified whenever feasible.
    362 </t>
    363 <t>
    364    The Last-Modified header field value is often used as a cache
    365    validator. In simple terms, a cache entry is considered to be valid
    366    if the representation has not been modified since the Last-Modified value.
    367 </t>
    368 </section>
    369 
    370 <section title="Entity Tags" anchor="entity.tags">
     359   An origin server &SHOULD; obtain the Last-Modified value of the
     360   representation as close as possible to the time that it generates
     361   the Date field-value for its response. This allows a recipient to
     362   make an accurate assessment of the representation's modification time,
     363   especially if the representation changes near the time that the
     364   response is generated.
     365</t>
     366<t>
     367   An origin server with a clock &MUST-NOT; send a Last-Modified date
     368   that is later than the server's time of message origination (Date).
     369   If the last modification time is derived from implementation-specific
     370   metadata that evaluates to some time in the future, according to the
     371   origin server's clock, then the origin server &MUST; replace that
     372   value with the message origination date. This prevents a future
     373   modification date from having an adverse impact on cache validation.
     374</t>
     375</section>
     376
     377<section title="Comparison" anchor="lastmod.comparison">
     378<t>
     379   A Last-Modified time, when used as a validator in a request, is
     380   implicitly weak unless it is possible to deduce that it is strong,
     381   using the following rules:
     382  <list style="symbols">
     383     <t>The validator is being compared by an origin server to the
     384        actual current validator for the representation and,</t>
     385     <t>That origin server reliably knows that the associated representation did
     386        not change twice during the second covered by the presented
     387        validator.</t>
     388  </list>
     389</t>
     390<t>
     391   or
     392  <list style="symbols">
     393     <t>The validator is about to be used by a client in an If-Modified-Since
     394        or If-Unmodified-Since header field, because the client
     395        has a cache entry for the associated representation, and</t>
     396     <t>That cache entry includes a Date value, which gives the time
     397        when the origin server sent the original response, and</t>
     398     <t>The presented Last-Modified time is at least 60 seconds before
     399        the Date value.</t>
     400  </list>
     401</t>
     402<t>
     403   or
     404  <list style="symbols">
     405     <t>The validator is being compared by an intermediate cache to the
     406        validator stored in its cache entry for the representation, and</t>
     407     <t>That cache entry includes a Date value, which gives the time
     408        when the origin server sent the original response, and</t>
     409     <t>The presented Last-Modified time is at least 60 seconds before
     410        the Date value.</t>
     411  </list>
     412</t>
     413<t>
     414   This method relies on the fact that if two different responses were
     415   sent by the origin server during the same second, but both had the
     416   same Last-Modified time, then at least one of those responses would
     417   have a Date value equal to its Last-Modified time. The arbitrary 60-second
     418   limit guards against the possibility that the Date and Last-Modified
     419   values are generated from different clocks, or at somewhat
     420   different times during the preparation of the response. An
     421   implementation &MAY; use a value larger than 60 seconds, if it is
     422   believed that 60 seconds is too short.
     423</t>
     424</section>
     425</section>
     426
     427<section title="ETag" anchor="header.etag">
     428  <iref primary="true" item="ETag header field" x:for-anchor=""/>
     429  <iref primary="true" item="Header Fields" subitem="ETag" x:for-anchor=""/>
     430  <x:anchor-alias value="ETag"/>
    371431  <x:anchor-alias value="entity-tag"/>
     432  <x:anchor-alias value="entity.tags"/>
    372433  <x:anchor-alias value="opaque-tag"/>
    373434  <x:anchor-alias value="weak"/>
    374435<t>
    375    Entity-tags are used for comparing two or more representations of the same
    376    resource. HTTP/1.1 uses entity-tags in the ETag (<xref target="header.etag"/>),
    377    If-Match (<xref target="header.if-match"/>), If-None-Match (<xref target="header.if-none-match"/>), and
    378    If-Range (&header-if-range;) header fields. The definition of how they
    379    are used and compared as cache validators is in <xref target="weak.and.strong.validators"/>. An
    380    entity-tag consists of an opaque quoted string, possibly prefixed by
    381    a weakness indicator.
    382 </t>
    383 <figure><artwork type="abnf2616"><iref primary="true" item="Grammar" subitem="entity-tag"/><iref primary="true" item="Grammar" subitem="weak"/><iref primary="true" item="Grammar" subitem="opaque-tag"/>
     436   The ETag header field provides the current entity-tag for the
     437   selected representation.
     438   An entity-tag is an opaque validator for differentiating between
     439   multiple representations of the same resource, regardless of whether
     440   those multiple representations are due to resource state changes over
     441   time, content negotiation resulting in multiple representations being
     442   valid at the same time, or both. An entity-tag consists of an opaque
     443   quoted string, possibly prefixed by a weakness indicator.
     444</t>
     445<figure><artwork type="abnf2616"><iref primary="true" item="Grammar" subitem="ETag"/><iref primary="true" item="Grammar" subitem="entity-tag"/><iref primary="true" item="Grammar" subitem="weak"/><iref primary="true" item="Grammar" subitem="opaque-tag"/>
     446  <x:ref>ETag</x:ref>       = <x:ref>entity-tag</x:ref>
     447
    384448  <x:ref>entity-tag</x:ref> = [ <x:ref>weak</x:ref> ] <x:ref>opaque-tag</x:ref>
    385449  <x:ref>weak</x:ref>       = <x:abnf-char-sequence>"W/"</x:abnf-char-sequence> ; "W/", case-sensitive
     
    387451</artwork></figure>
    388452<t>
    389    A "strong entity-tag" &MAY; be shared by two representations of a resource
    390    only if they are equivalent by octet equality.
    391 </t>
    392 <t>
    393    A "weak entity-tag", indicated by the "W/" prefix, &MAY; be shared by
    394    two representations of a resource. A weak entity-tag can only be used
    395    for weak comparison.
    396 </t>
    397 <t>
    398    Cache entries might persist for arbitrarily long periods, regardless
    399    of expiration times, so it is inappropriate to expect that a cache will
    400    never again attempt to validate an entry using a validator that it
    401    obtained at some point in the past.
    402    A strong entity-tag &MUST; be unique across all versions of all
    403    representations associated with a particular resource over time.
    404    However, there is no implication of uniqueness across entity-tags
    405    of different resources (i.e., the same entity-tag value might be
    406    in use for representations of multiple resources at the same time
    407    and does not imply that those representations are equivalent).
    408 </t>
    409 
    410 <section title="ETag" anchor="header.etag">
    411   <iref primary="true" item="ETag header field" x:for-anchor=""/>
    412   <iref primary="true" item="Header Fields" subitem="ETag" x:for-anchor=""/>
    413   <x:anchor-alias value="ETag"/>
    414 <t>
    415    The "ETag" header field provides the current value of the
    416    entity-tag (see <xref target="entity.tags"/>) for one representation of
    417    the target resource.  An entity-tag
    418    is intended for use as a resource-local identifier for differentiating
    419    between representations of the same resource that vary over time or via
    420    content negotiation (see <xref target="weak.and.strong.validators"/>).
    421 </t>
    422 <figure><artwork type="abnf2616"><iref primary="true" item="Grammar" subitem="ETag"/>
    423   <x:ref>ETag</x:ref> = <x:ref>entity-tag</x:ref>
    424 </artwork></figure>
     453   An entity-tag can be more reliable for validation than a modification
     454   date in situations where it is inconvenient to store modification
     455   dates, where the one-second resolution of HTTP date values is not
     456   sufficient, or where modification dates are not consistently maintained.
     457</t>
    425458<figure><preamble>
    426459  Examples:
     
    431464  ETag: ""
    432465</artwork></figure>
    433 <t>
    434    An entity-tag provides an "opaque" cache validator that allows for
    435    more reliable validation than modification dates in situations where
    436    it is inconvenient to store modification dates,
    437    where the one-second resolution of HTTP date values is not
    438    sufficient, or where the origin server wishes to avoid certain
    439    paradoxes that might arise from the use of modification dates.
    440 </t>
     466
     467<section title="Generation" anchor="entity.tag.generation">
    441468<t>
    442469   The principle behind entity-tags is that only the service author
    443    knows the semantics of a resource well enough to select an
    444    appropriate cache validation mechanism, and the specification of any
    445    validator comparison function more complex than byte-equality would
    446    open up a can of worms. Thus, comparisons of any other header fields
    447    (except Last-Modified, for compatibility with HTTP/1.0) are never
    448    used for purposes of validating a cache entry.
    449 </t>
    450 </section>
    451 
    452 <section title="Example: Entity-tags varying on Content-Negotiated Resources" anchor="example.entity.tag.vs.conneg">
    453 <t>
    454    Consider a resource that is subject to content negotiation (&content-negotiation;),
    455    and where the representations returned upon a GET request vary based on
    456    the Accept-Encoding request header field (&header-accept-encoding;):
    457 </t>
    458 <figure><preamble>>> Request:</preamble><artwork type="message/http; msgtype=&#34;request&#34;"  x:indent-with="  ">
    459 GET /index HTTP/1.1
    460 Host: www.example.com
    461 Accept-Encoding: gzip
    462 
    463 </artwork></figure>
    464 <t>
    465    In this case, the response might or might not use the gzip content coding.
    466    If it does not, the response might look like:
    467 </t>
    468 <figure><preamble>>> Response:</preamble><artwork type="message/http; msgtype=&#34;response&#34;"  x:indent-with="  ">
    469 HTTP/1.1 200 OK
    470 Date: Thu, 26 Mar 2010 00:05:00 GMT
    471 ETag: "123-a"
    472 Content-Length: <x:length-of target="exbody"/>
    473 Vary: Accept-Encoding
    474 Content-Type: text/plain
    475 
    476 <x:span anchor="exbody">Hello World!
    477 Hello World!
    478 Hello World!
    479 Hello World!
    480 Hello World!
    481 </x:span></artwork></figure>
    482 <t>
    483    An alternative representation that does use gzip content coding would be:
    484 </t>
    485 <figure><preamble>>> Response:</preamble><artwork type="message/http; msgtype=&#34;response&#34;"  x:indent-with="  ">
    486 HTTP/1.1 200 OK
    487 Date: Thu, 26 Mar 2010 00:05:00 GMT
    488 ETag: "123-b"
    489 Content-Length: 43
    490 Vary: Accept-Encoding
    491 Content-Type: text/plain
    492 Content-Encoding: gzip
    493 
    494 <spanx>...binary data...</spanx></artwork></figure>
    495 <x:note>
    496   <t>
    497     <x:h>Note:</x:h> Content codings are a property of the representation,
    498     so therefore an entity-tag of an encoded representation must be distinct
    499     from an unencoded representation to prevent conflicts during cache updates
    500     and range requests.  In contrast, transfer codings (&transfer-codings;)
    501     apply only during message transfer and do not require distinct entity-tags.
    502   </t>
    503 </x:note>
    504 </section>
    505 </section>
    506 
    507 <section title="Weak and Strong Validators" anchor="weak.and.strong.validators">
     470   knows the implementation of a resource well enough to select the
     471   most accurate and efficient validation mechanism for that resource,
     472   and that any such mechanism can be mapped to a simple sequence of
     473   octets for easy comparison.  Since the value is opaque, there is no
     474   need for the client to be aware of how each entity-tag is constructed.
     475</t>
     476<t>
     477   For example, a resource that has implementation-specific versioning
     478   applied to all changes might use an internal revision number, perhaps
     479   combined with a variance identifier for content negotiation, to
     480   accurately differentiate between representations.
     481   Other implementations might use a stored hash of representation content,
     482   a combination of various filesystem attributes, or a modification
     483   timestamp that has sub-second resolution.
     484</t>
     485<t>
     486   Origin servers &SHOULD; send ETag for any selected representation
     487   for which detection of changes can be reasonably and consistently
     488   determined, since the entity-tag's use in conditional requests and
     489   evaluating cache freshness (&caching;) can result in a substantial
     490   reduction of HTTP network traffic and can be a significant factor in
     491   improving service scalability and reliability.
     492</t>
     493</section>
     494
     495<section title="Weak versus Strong" anchor="weak.and.strong.validators">
    508496<t>
    509497   Since both origin servers and caches will compare two validators to
    510    decide if they represent the same or different representations, one
     498   decide if they indicate the same or different representations, one
    511499   normally would expect that if the representation (including both
    512500   representation header fields and representation body) changes in any
    513501   way, then the associated validator would change as well. If this is
    514    true, then we call this validator a "strong validator".  One example
     502   true, then we call that validator a "strong validator".  One example
    515503   of a strong validator is an integer that is incremented in stable
    516504   storage every time a representation is changed.
     
    529517</t>
    530518<t>
     519   One can think of a strong validator as part of an identifier for a
     520   specific representation, whereas a weak validator is part of an
     521   identifier for a set of equivalent representations (where this notion
     522   of equivalence is entirely governed by the origin server and beyond
     523   the scope of this specification).
     524</t>
     525<t>
    531526   An entity-tag is normally a strong validator, but the protocol
    532    provides a mechanism to tag an entity-tag as "weak". One can think
    533    of a strong validator as part of an identifier for a specific
    534    representation, whereas a weak validator is part of an identifier
    535    for a set of equivalent representations (where this notion of
    536    equivalence is entirely governed by the origin server and beyond
    537    the scope of this specification).
     527   provides a mechanism to tag an entity-tag as "weak".
    538528  <list><t>
    539529      A representation's modification time, if defined with only one-second
     
    556546</t>
    557547<t>
    558    A "use" of a validator is either when a client generates a request
    559    and includes the validator in a validating header field, or when a
    560    server compares two validators.
    561 </t>
    562 <t>
    563    Strong validators are usable in any context. Weak validators are only
    564    usable in contexts that do not depend on exact equality of a representation.
    565    For example, either kind is usable for a normal conditional GET.
    566    However, only a strong validator is usable for range retrieval
    567    (<xref target="Part5"/>), since otherwise the client might end up
    568    with an internally inconsistent representation.
    569    Clients &MUST-NOT; use weak validators in range requests.
    570 </t>
    571 <t>
    572    The only function that HTTP/1.1 defines on validators is
    573    comparison. There are two validator comparison functions, depending
     548   A "strong entity-tag" &MAY; be shared by two representations of a resource
     549   only if they are equivalent by octet equality.
     550</t>
     551<t>
     552   A "weak entity-tag", indicated by the "W/" prefix, &MAY; be shared by
     553   two representations of a resource. A weak entity-tag can only be used
     554   for weak comparison.
     555</t>
     556<t>
     557   Cache entries might persist for arbitrarily long periods, regardless
     558   of expiration times.  Thus, a cache might attempt to validate an
     559   entry using a validator that it obtained in the distant past.
     560   A strong entity-tag &MUST; be unique across all versions of all
     561   representations associated with a particular resource over time.
     562   However, there is no implication of uniqueness across entity-tags
     563   of different resources (i.e., the same entity-tag value might be
     564   in use for representations of multiple resources at the same time
     565   and does not imply that those representations are equivalent).
     566</t>
     567</section>
     568
     569<section title="Comparison" anchor="entity.tag.comparison">
     570  <x:anchor-alias value="validator.comparison"/>
     571<t>
     572   There are two entity-tag comparison functions, depending
    574573   on whether the comparison context allows the use of weak validators
    575574   or not:
     
    585584</t>
    586585<t>
     586   A "use" of a validator is either when a client generates a request
     587   and includes the validator in a precondition, or when a server
     588   compares two validators.
     589</t>
     590<t>
     591   Strong validators are usable in any context. Weak validators are only
     592   usable in contexts that do not depend on exact equality of a representation.
     593   For example, either kind is usable for a normal conditional GET.
     594</t>
     595<t>
    587596   The example below shows the results for a set of entity-tag pairs,
    588597   and both the weak and strong comparison function results:
     
    616625<t>
    617626   An entity-tag is strong unless it is explicitly tagged as weak.
    618    <xref target="entity.tags"/> gives the syntax for entity-tags.
    619 </t>
    620 <t>
    621    A Last-Modified time, when used as a validator in a request, is
    622    implicitly weak unless it is possible to deduce that it is strong,
    623    using the following rules:
    624   <list style="symbols">
    625      <t>The validator is being compared by an origin server to the
    626         actual current validator for the representation and,</t>
    627      <t>That origin server reliably knows that the associated representation did
    628         not change twice during the second covered by the presented
    629         validator.</t>
    630   </list>
    631 </t>
    632 <t>
    633    or
    634   <list style="symbols">
    635      <t>The validator is about to be used by a client in an If-Modified-Since
    636         or If-Unmodified-Since header field, because the client
    637         has a cache entry for the associated representation, and</t>
    638      <t>That cache entry includes a Date value, which gives the time
    639         when the origin server sent the original response, and</t>
    640      <t>The presented Last-Modified time is at least 60 seconds before
    641         the Date value.</t>
    642   </list>
    643 </t>
    644 <t>
    645    or
    646   <list style="symbols">
    647      <t>The validator is being compared by an intermediate cache to the
    648         validator stored in its cache entry for the representation, and</t>
    649      <t>That cache entry includes a Date value, which gives the time
    650         when the origin server sent the original response, and</t>
    651      <t>The presented Last-Modified time is at least 60 seconds before
    652         the Date value.</t>
    653   </list>
    654 </t>
    655 <t>
    656    This method relies on the fact that if two different responses were
    657    sent by the origin server during the same second, but both had the
    658    same Last-Modified time, then at least one of those responses would
    659    have a Date value equal to its Last-Modified time. The arbitrary 60-second
    660    limit guards against the possibility that the Date and Last-Modified
    661    values are generated from different clocks, or at somewhat
    662    different times during the preparation of the response. An
    663    implementation &MAY; use a value larger than 60 seconds, if it is
    664    believed that 60 seconds is too short.
    665 </t>
    666 <t>
    667    If a client wishes to perform a sub-range retrieval on a value for
    668    which it has only a Last-Modified time and no opaque validator, it
    669    &MAY; do this only if the Last-Modified time is strong in the sense
    670    described here.
    671 </t>
    672 <t>
    673    A cache or origin server receiving a conditional range request
    674    (<xref target="Part5"/>) &MUST; use the strong comparison function to
    675    evaluate the condition.
    676 </t>
    677 <t>
    678    These rules allow HTTP/1.1 caches and clients to safely perform sub-range
    679    retrievals on values that have been obtained from HTTP/1.0
    680    servers.
    681627</t>
    682628</section>
     
    760706</section>
    761707
     708<section title="Example: Entity-tags varying on Content-Negotiated Resources" anchor="example.entity.tag.vs.conneg">
     709<t>
     710   Consider a resource that is subject to content negotiation (&content-negotiation;),
     711   and where the representations returned upon a GET request vary based on
     712   the Accept-Encoding request header field (&header-accept-encoding;):
     713</t>
     714<figure><preamble>>> Request:</preamble><artwork type="message/http; msgtype=&#34;request&#34;"  x:indent-with="  ">
     715GET /index HTTP/1.1
     716Host: www.example.com
     717Accept-Encoding: gzip
     718
     719</artwork></figure>
     720<t>
     721   In this case, the response might or might not use the gzip content coding.
     722   If it does not, the response might look like:
     723</t>
     724<figure><preamble>>> Response:</preamble><artwork type="message/http; msgtype=&#34;response&#34;"  x:indent-with="  ">
     725HTTP/1.1 200 OK
     726Date: Thu, 26 Mar 2010 00:05:00 GMT
     727ETag: "123-a"
     728Content-Length: <x:length-of target="exbody"/>
     729Vary: Accept-Encoding
     730Content-Type: text/plain
     731
     732<x:span anchor="exbody">Hello World!
     733Hello World!
     734Hello World!
     735Hello World!
     736Hello World!
     737</x:span></artwork></figure>
     738<t>
     739   An alternative representation that does use gzip content coding would be:
     740</t>
     741<figure><preamble>>> Response:</preamble><artwork type="message/http; msgtype=&#34;response&#34;"  x:indent-with="  ">
     742HTTP/1.1 200 OK
     743Date: Thu, 26 Mar 2010 00:05:00 GMT
     744ETag: "123-b"
     745Content-Length: 43
     746Vary: Accept-Encoding
     747Content-Type: text/plain
     748Content-Encoding: gzip
     749
     750<spanx>...binary data...</spanx></artwork></figure>
     751<x:note>
     752  <t>
     753    <x:h>Note:</x:h> Content codings are a property of the representation,
     754    so therefore an entity-tag of an encoded representation must be distinct
     755    from an unencoded representation to prevent conflicts during cache updates
     756    and range requests.  In contrast, transfer codings (&transfer-codings;)
     757    apply only during message transfer and do not require distinct entity-tags.
     758  </t>
     759</x:note>
     760</section>
     761</section>
    762762</section>
    763763
     
    10061006   field and either an If-None-Match or an If-Modified-Since header
    10071007   fields is undefined by this specification.
     1008</t>
     1009</section>
     1010
     1011<section title="If-Range" anchor="header.if-range">
     1012<t>
     1013   The If-Range header field provides a special conditional request
     1014   mechanism that is similar to If-Match and If-Unmodified-Since but
     1015   specific to HTTP range requests. If-Range is defined in &header-if-range;.
    10081016</t>
    10091017</section>
Note: See TracChangeset for help on using the changeset viewer.