":" in Accept; Change to Section 14.1 of draft-ietf-http-v11-spec-05

Alexei Kosut and I have been testing the (relatively) recent proposed
change in the syntax of Accept for HTTP/1.1 and its affect on current
HTTP/1.0 servers that have already implemented content negotiation.

   Executive summary:  it breaks all known existing practice

Existing practice expects a semicolon ";" to separate all parameters,
reserving only the "q" and "mxb" parameter names for use by the negotiation
algorithm.  For example

    Accept: image/png; image/gif;q=0.4, image/tiff;q=0.8

Draft 05 requires the use of a ":" to separate the negotiation parameters
from any media type parameters, as in

    Accept: image/png; image/gif:q=0.4, image/tiff:q=0.8

for the sole purpose of removing the potential ambiguity that existed in
the older syntax, particularly given the possiblility of future extensions.

Although that was a worthy goal, it causes all of the tested servers to
give the wrong response (sometimes drastically wrong) to what would be
a valid (and common) HTTP/1.1 request.  For example, let's imagine that a
request containing the above request-header (common for requests of in-line
images) was sent in a GET to a resource with a 200 response available in
both image/gif and image/tiff.  The response from the following tested
servers would be

   Apache/1.0.5             ---> 404 Not found
   CERN/3.0                 ---> the image with the highest source quality
   Spyglass_Server/1.20fc7  ---> 406 None Acceptable

In contrast, using the former Accept request-header (with ";") gives

   Apache/1.0.5             ---> image/tiff
   CERN/3.0                 ---> image/tiff
   Spyglass_Server/1.20fc7  ---> image/tiff

as would be expected.  Note that these are actual test results -- I can
make the full request traces available if necessary.

In other words, the change to ":" would make Accept unusable by any client
until all HTTP/1.0 servers were replaced by HTTP/1.1 servers, because it
is an incompatible change to the protocol which is sent prior to knowing
the protocol capability of the recipient.

After checking various options, we have come to the conclusion that there
is only one way to properly solve this problem which can balance both the
desire for unambiguous parsing and compatibility with the over 100,000
existing web servers capable of content negotiation.  Doing so will
require the following change (indicated by a diff -C3) to
Section 14.1 of draft-ietf-http-v11-spec-05.txt:

======================================================================
*** draft-ietf-http-v11-spec-05.txt	Mon Jun 10 15:40:01 1996
--- accept.txt	Sun Jun 23 08:56:23 1996
***************
*** 4968,5026 ****
  to indicate that the request is specifically limited to a small set of
  desired types, as in the case of a request for an in-line image.
  
!        Accept         = "Accept" ":" #(
!                              media-range
!                              [ ( ":" | ";" )
!                                range-parameter
!                                *( ";" range-parameter ) ]
!                             | extension-token )
  
!        media-range    = ( "*/*"
!                         | ( type "/" "*" )
!                         | ( type "/" subtype )
!                         ) *( ";" parameter )
  
!        range-parameter = ( "q" "=" qvalue )
!                        | extension-range-parameter
  
!        extension-range-parameter = ( token "=" token )
! 
!        extension-token = token
  
  The asterisk "*" character is used to group media types into ranges,
  with "*/*" indicating all media types and "type/*" indicating all
! subtypes of that type. The range-parameter q is used to indicate the
! media type quality factor for the range, which represents the user's
! preference for that range of media types. The default value is q=1. In
! Accept headers sent by HTTP/1.1 clients, the character separating media-
! ranges from range-parameters MUST be a ":". HTTP/1.1 servers SHOULD be
! tolerant of use of the ";" separator by HTTP/1.0 clients.
  
  The example
  
!        Accept: audio/*: q=0.2, audio/basic
  
  SHOULD be interpreted as "I prefer audio/basic, but send me any audio
  type if it is the best available after an 80% mark-down in quality."
  
! If no Accept header is present, then it is assumed that the client
! accepts all media types. If Accept headers are present, and if the
! server cannot send a response which is acceptable according to the
! Accept headers, then the server SHOULD send an error response with the
! 406 (not acceptable) status code, though the sending of an unacceptable
! response is also allowed.
  
  A more elaborate example is
  
!        Accept: text/plain: q=0.5, text/html,
!                text/x-dvi: q=0.8, text/x-c
  
  Verbally, this would be interpreted as "text/html and text/x-c are the
  preferred media types, but if they do not exist, then send the text/x-
--- 4968,5023 ----
  to indicate that the request is specifically limited to a small set of
  desired types, as in the case of a request for an in-line image.
  
!        Accept           = "Accept" ":"
!                           #( media-range [ accept-params ] )
  
!        media-range      = ( "*/*"
!                           | ( type "/" "*" )
!                           | ( type "/" subtype )
!                           ) *( ";" parameter )
  
!        accept-params    = ";" "q" "=" qvalue *( accept-extension )
  
!        accept-extension = ";" token [ "=" ( token | quoted-string ) ]
  
  The asterisk "*" character is used to group media types into ranges,
  with "*/*" indicating all media types and "type/*" indicating all
! subtypes of that type. The media-range MAY include media type parameters
! that are applicable to that range.
! 
! Each media-range MAY be followed by one or more accept-params, beginning
! with the "q" parameter for indicating a relative quality factor. The
! first "q" parameter (if any) separates the media-range parameter(s) from
! the accept-params. Quality factors allow the user or user agent to
! indicate the relative degree of preference for that media-range, using
! the qvalue scale from 0 to 1 (section 3.9). The default value is q=1.
! 
!   Note: Use of the "q" parameter name to separate media type parameters
!   from Accept extension parameters is due to historical practice.
!   Although this prevents any media type parameter named "q" from being
!   used with a media range, such an event is believed to be unlikely
!   given the lack of any "q" parameters in the IANA media type registry
!   and the rare usage of any media type parameters in Accept. Future
!   media types should be discouraged from registering any parameter named
!   "q".
  
  The example
  
!        Accept: audio/*; q=0.2, audio/basic
  
  SHOULD be interpreted as "I prefer audio/basic, but send me any audio
  type if it is the best available after an 80% mark-down in quality."
  
! If no Accept header field is present, then it is assumed that the client
! accepts all media types. If an Accept header field is present, and if
! the server cannot send a response which is acceptable according to the
! combined Accept field value, then the server SHOULD send a 406 (not 
! acceptable) response.
  
  A more elaborate example is
  
!        Accept: text/plain; q=0.5, text/html,
!                text/x-dvi; q=0.8, text/x-c
  
  Verbally, this would be interpreted as "text/html and text/x-c are the
  preferred media types, but if they do not exist, then send the text/x-
***************
*** 5050,5057 ****
  INTERNET-DRAFT            HTTP/1.1     Sunday, June 09, 1996
  
  
!        Accept: text/*:q=0.3, text/html:q=0.7, text/html;level=1,
!                text/html;level=2:q=0.4, */*:q=0.5
  
  would cause the following values to be associated:
  
--- 5047,5054 ----
  INTERNET-DRAFT            HTTP/1.1     Sunday, June 09, 1996
  
  
!        Accept: text/*;q=0.3, text/html;q=0.7, text/html;level=1,
!                text/html;level=2;q=0.4, */*;q=0.5
  
  would cause the following values to be associated:
  
***************
end-of-diff
======================================================================

I am hoping that the above is self-explanatory (as it should be if we
want implementers to understand it).  Yes, I know that this requires
a change to draft 05, which is currently in last call, but that cannot
be avoided.


 ...Roy T. Fielding
    Department of Information & Computer Science    (fielding@ics.uci.edu)
    University of California, Irvine, CA 92717-3425    fax:+1(714)824-4056
    http://www.ics.uci.edu/~fielding/

Received on Sunday, 23 June 1996 10:24:39 UTC