mjackson / rack-accept

HTTP Accept* for Ruby/Rack
http://mjackson.github.com/rack-accept
47 stars 16 forks source link

Incorrect q value, when grouping multiple media types with a single q value #13

Closed kamui closed 12 years ago

kamui commented 12 years ago

I noticed this bug when playing with multiple media types and q values.

An accepts header like this:

application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5

should generate a qvalues hash like this:

{
  "application/xml" => 0.9,
  "application/xhtml+xml" => 0.9,
  "text/html" => 0.9,
  "text/plain" => 0.8,
  "*/*" => 0.5
} 

But rack-accept splits the header on , and then assumes any type without a q value will have a q value of 1. So we get this instead:

{
  "application/xml" => 1,
  "application/xhtml+xml" => 1,
  "text/html" => 0.9,
  "text/plain" => 0.8,
  "*/*" => 0.5
} 

This is might be a complicated problem to solve, since you'd have to regex for accept-extensions and then apply those values to all the media types that came before it.

mjackson commented 12 years ago

I'm pretty sure this isn't a bug, it's a feature. To quote the spec:

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.

In your example, since application/xml and application/xhtml+xml don't explicitly specify a qvalue it should default to 1. The comma is indeed a delimiter, and does not mean "use the qvalue of whatever comes after me".

kamui commented 12 years ago

Ahh.. that makes so much more sense. I read the spec wrong, or misread examples of it. Thanks!