Repository navigation
Conversation
A media range with q=0 means the client does not accept it (RFC 9110, section 12.4.2), but accepts/2 still used such entries once nothing better matched. "Accept: application/json;q=0" set the json format, and so did "*/*;q=0". A wildcard also picked a format the header refused, for example json for "application/json;q=0, */*" and html for "text/html;q=0, */*". Entries with q=0 are no longer used, and formats refused by a specific media type are not picked through a wildcard or the html fallback. When nothing else matches, Phoenix.NotAcceptableError is raised.
|
Three cases worth discussing if we touch this code
|
A format is refused when the most specific media range matching its media type has q=0 (RFC 9110, section 12.5.1), so "*/*;q=0" and "text/*;q=0" now refuse the formats they cover, while "text/html, text/*;q=0" still accepts html and "text/html;level=1;q=0" no longer refuses text/html. The */* browser fallback to html only applies when */* has a positive q and html is not refused.
|
All three are handled now (6b2b37c).
|
|
I'm wondering about the performance implications, since we now do more work for each request - cc @josevalim |
|
The accepts header has been historically a pain to deal with because browsers and clients sent all kinds of things expecting different results. Generally speaking, I'd be fine with following the RFC to the letter, but accept has been anything but consistent, and trying to deal with a case of q=0 which will always lead to a failure only adds complexity. So I am 👎, thanks. |
|
Understood, thanks for taking a look. Closing. |
A media range with
q=0means the client does not accept that type (RFC 9110, section 12.4.2).accepts/2only gaveq=1entries priority, and once nothing better matched it fell back to the remaining entries, including theq=0ones. Wildcards didn't look at refusals either:Accept: application/json;q=0withaccepts(conn, ["json"])set thejsonformat instead of raisingPhoenix.NotAcceptableError.Accept: */*;q=0did the same.Accept: application/json;q=0, */*with["json", "text"]pickedjsonthrough*/*. The same happened when*/*came first.Accept: text/html;q=0, */*with["html", "json"]pickedhtmlthrough the browser fallback.With this change, entries with
q=0are never used, and formats refused by a specific media type are taken out of the candidates before matching. So neither a wildcard nor the*/*html fallback can pick them. If nothing is left,Phoenix.NotAcceptableErroris raised as before, andexception.acceptsstill lists every format the server offered. Headers without aq=0entry give the same results as before.The new test "never picks a media type refused with q=0" in
test/phoenix/controller/controller_test.exsfails without the change (jsonis picked instead oftext).mix format --check-formattedandmix compile --warnings-as-errorsare clean, andtest/phoenix/controller/controller_test.exspasses (72 tests).