Explore making support for q parameter more compatible with RFC2616
@glassfishrobot is already working on this.
Since Feb 10, 2018.
- Dominant language
- Java
- Stars
- 400
- Forks
- 143
- PR merge metrics
- No merged PRs in 30d
Description
From "Ron Sigal":
I was surprised that the algorithm in Section 3.8 of the JAX-RS spec seems to be inconsistent with the algorithm implicit in http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1, which I described on RESTEASY-994 as
1. Let PO = the partial order on accepted media types induced by "is less specific than".
2. Add "dummy/dummy;q=0" as the minimal element in PO, where "dummy/dummy;q=0" is a wildcard like "/"
3. For each M in available media types:
Let Q_M = max
{ q | q is the quality factor of a maximal element in PO }
4. Let Q = max
{ Q_M | M in available media types }
5. Let MT =
{ M | M is an available media type such that M_Q = Q }
6. If no element in MT matches an accepted media type, return a "406" response.
7. Return an arbitrary element of MT
Actually, there are a couple of gaps in http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1:
1. There is no mention of tie breaking in the case that multiple available media type are assigned the same quality factor. I think that the consensus on RESTEASY-994 is that the available media type that matches the more specific requested media range should be given preference. For example, given
Accept: application/json, /
application/json and application/xml would both have a quality factor of 1.0, but application/json should be preferred. Step 7 could be changed to implement tie breaking based on specificity.
2. There is no precise definition of "more specific". For example, I would expect application/json to be more specific that /;a=1;b=2;c=3, but Resteasy currently prefers the latter because it counts the number of parameters. I think that should be changed with the ordering defined:
media type 1 is more specific than media type 2 if and only if
- media type 1 has a non wildcard type and media type 2 has a wildcard type, or
- media type 1 has a non wildcard subtype and media type 2 has a wildcard subtype, or
- media type 1 has more parameters than media type 2
3. It's a minor thing, but there's no suggestion for what to do with
Accept: application/json, application/xml, application/json;q=0.5
Anyway, the way things are, Request.selectVariant() is governed by http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14 (I guess), and negotiation based on the @Produces annotation is governed by Section 3.8 of the JAX-RS spec, and I believe they can legally return different results. In particular, the JAX-RS algorithm doesn't have a notion of basing the quality factor of an available media type on the most specific matching requested media range. For example, given the somewhat artificial case
Accept; application/json;q=0.5, application/*
and
@Produces("application/json, application/xml")
the HTTP algorithm would assign a quality factor of 0.5 to application/json because application/json;q=0.5 is more specific than application/*, but the JAX-RS algorithm gives
M = { S("application/json;q=0.5", "application/json"), S("application/", "application/json"), S("application/", "application/xml")
{ application/json;q=0.5, application/json;q=1.0, application/xml;q=1.0 }
where
application/json;q=1.0 >= application/xml;q=1.0 > application/json;q=0.5
and
application/xml;q=1.0 >= application/json;q=1.0 > application/json;q=0.5
are both legal orderings, so that either application/json or application/xml could be returned.
Affected Versions
[2.1]
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.