- From: Roy T. Fielding <fielding@liege.ICS.UCI.EDU>
- Date: Sun, 23 Jun 1996 10:15:36 -0700
- To: http-wg%cuckoo.hpl.hp.com@hplb.hpl.hp.com
- Cc: Alexei Kosut <akosut@organic.com>
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