Content negotiation appears to ignore Accept header q-values (q=0) during renderer selection #9986
Replies: 5 comments 1 reply
-
|
Your two examples match the current DRF behavior, and the docs describe it as intentional.
The content negotiation docs also say that So with the default negotiator, |
Beta Was this translation helpful? Give feedback.
-
|
Thanks for flagging this. I didn't know about quality values for that header, but that makes sense, yes. I've looked at the PRs when content negotiation was touched and didn't find any mention of it, so not sure if it was left out on purpose, but given that it's documented it might be the case. The cases you gave sound quite niche to me, and it feels like the client would be better off requesting what they want rather than what they don't. I can't find a lot of folks requesting this so that, which confirm my sentiment. I wonder how complicated adding support would be though, if the change is minimal and targeted, that could be fine maybe? I haven't looked at it in details though... |
Beta Was this translation helpful? Give feedback.
-
|
Thanks for checking this. I agree this should not be treated as a small accidental bug if the current behavior is documented. I can try a small prototype to see how invasive proper My plan would be:
If the implementation turns out to be invasive or risky for backwards compatibility, I’ll report back here rather than opening a large PR. |
Beta Was this translation helpful? Give feedback.
-
|
@browniebroke I tested a minimal prototype locally. It keeps the existing behavior for Focused negotiation tests pass locally: |
Beta Was this translation helpful? Give feedback.
-
|
Thanks everyone for the feedback. I put together a minimal prototype based on the discussion and opened a focused PR for easier review: #9988. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Summary
While reviewing DRF's content negotiation behavior, I noticed what appears to be an inconsistency with HTTP
Acceptheader quality (q) values.From my local investigation, media types explicitly marked with
q=0("not acceptable") can still be selected during renderer negotiation.Before preparing a patch, I wanted to confirm whether this is intentional behavior or an issue that should be addressed.
Reproduction
Using a local checkout of the current main branch, I tested the following scenarios.
Case 1
Request:
Accept: text/html;q=0, */*;q=1Observed renderer:
Expected renderer:
since
text/htmlis explicitly marked as unacceptable.Case 2
Request:
Accept: application/json;q=0, text/html;q=1Observed renderer:
Expected renderer:
because
application/jsonhasq=0.Investigation
From local inspection, renderer selection appears to be performed by:
rest_framework/negotiation.pyDefaultContentNegotiation.select_renderer()DefaultContentNegotiation.get_accept_list()together with media type matching utilities in:
rest_framework/utils/mediatypes.pyThe current implementation appears to match media types based on precedence and specificity but does not appear to consider HTTP quality values when selecting a renderer.
Validation
I added two focused local tests:
test_client_excludes_zero_quality_media_typetest_client_prefers_nonzero_quality_media_typeand executed:
Result:
The failures consistently reproduce the behavior described above.
Expected Behavior
According to HTTP content negotiation semantics, media ranges with
q=0should be treated as unacceptable, and media types with higher nonzero quality values should be preferred during renderer selection.Question
Is the current behavior intentional for backwards compatibility, or would a change to honor
qvalues (particularlyq=0) be considered acceptable?If this is considered an issue, I'd be happy to prepare a focused PR with tests and a minimal implementation.
Beta Was this translation helpful? Give feedback.
All reactions