playframework/playframework — pull request #1416 by jroper (2013-08-01 06:48:22+00:00)
Title: Spec compliant media type parsing

Parsing media types is actually very complex, and previously Play was doing a
hacky series of splits, which usually work, but as soon as something slightly
different from what typical clients send came, would not work at all.

The following changes have been made:

* New MediaType class that has the type, plus a sequence of the
parameters, parsed according to RFC 2616, so they support everything
including quoted parameter values, parameterless values, etc etc.
* New mediaType method on RequestHeader for parsing the Content-Type.
* contentType and charset methods on RequestHeader now use the new
mediaType method to correctly parse the header.
* multipart/form-data now uses the mediaType method to correctly get the
boundary parameter, fixing #1399.
* MediaRange now extends MediaType, and has a q value and a sequence of
accept extensions.
* MediaRange sorting is now stable, equal q value/specificity media
ranges are in the same order as in the Accept header.

The new parser uses Scala parser combinators. In order to correctly parse
quoted parameters, a parser like this was necessary, since delimiters may
appear in the quoted values, which would break split. A benchmark of a
relatively complex accept header (6 elements) showed it takes 40us to parse
it on my machine.

At some point in future we may decide to extract some of the parsing out into
a generic class for reuse in other parts of Play, but for now I just wanted
to get this fix finished without over engineering.