Fix parsing of Accept header like '*/*;q=0.8' (#16169)

This fixes #15043

The issue is that browsers like "text/html,...,*/*;q=0.8" (see for
instance https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation/List_of_default_Accept_values
)

Without this commit we end up with an array of accepted type like
`("text/html", "*/*;q=0.8)` so when we then check if the array contains
`*/*` the check fails, and we return a 406 even though the client is
able to get the response.

This commit fixes it by removing the `;q=0.8` part.

(Ideally we should not just discard that part, we should extract that
 value, and order by it. See
 https://developer.mozilla.org/en-US/docs/Glossary/Quality_values for
 more info about that. However this could be done in a subsequent PR:
 this already fixes the 406 error, which is pretty blocking)
This commit is contained in:
Guillaume Turri 2023-07-24 05:34:12 +02:00 committed by GitHub
parent c71b48fe1a
commit 20d1743a36
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 6 additions and 0 deletions

View File

@ -183,6 +183,9 @@ class Controller extends AbstractController
// Figure out what the client accepts
$accept = preg_split("/[\s,]+/", $accept);
// Remove q-factor weighting. E.g. "application/json;q=0.8" becomes "application/json"
$accept = array_map(function ($type) {return explode(';', $type)[0];}, $accept);
if (in_array('*/*', $accept) || in_array('application/*', $accept)) {
// Prefer JSON if the client has no preference
if (in_array('application/json', $produced)) {

View File

@ -193,6 +193,9 @@ class Controller extends AbstractController
// Figure out what the client accepts
$accept = preg_split("/[\s,]+/", $accept);
// Remove q-factor weighting. E.g. "application/json;q=0.8" becomes "application/json"
$accept = array_map(function ($type) {return explode(';', $type)[0];}, $accept);
if (in_array('*/*', $accept) || in_array('application/*', $accept)) {
// Prefer JSON if the client has no preference
if (in_array('application/json', $produced)) {