Skip to content

Conversation

@yoeunes
Copy link
Contributor

@yoeunes yoeunes commented Nov 3, 2025

Q A
Branch? 6.4
Bug fix? yes
New feature? no
BC breaks? no
Deprecations? no
Issues Fixes #62282
License MIT

This PR fixes a bug in AcceptHeader where items with the same media type but different parameters (e.g., text/plain;format=flowed and text/plain;format=fixed) would overwrite each other.

The add() method now uses a canonical key that includes all parameters (except q), ensuring distinct items are stored correctly.

Consequently, the get() method has been updated to perform proper content negotiation (as described in RFC 9110), including matching parameters and sorting by specificity (e.g., text/plain > text/* > */*). New tests are added to cover these cases.

@yoeunes yoeunes force-pushed the httpfoundation-acceptheader-params branch 2 times, most recently from b72a7a0 to c99d747 Compare November 3, 2025 10:02
@Spomky
Copy link
Contributor

Spomky commented Nov 3, 2025

Hi @yoeunes,

From what I understand, this looks more like an enhancement of the existing behaviour rather than a bug fix. Is that correct?
If it is indeed a bug fix, it should probably target 6.4 instead of 7.4.

Thanks!

@yoeunes
Copy link
Contributor Author

yoeunes commented Nov 3, 2025

Hi @Spomky, I consider this a bug fix because the current implementation incorrectly overwrites header items (e.g., text/plain;format=flowed (q=1.0) is lost if text/plain;format=fixed (q=0.4) is also present) which breaks content negotiation

If it's confirmed as a bug fix, should I rebase this onto 6.4 instead? Let me know your thoughts or if more details are needed

Copy link
Contributor

@andesk andesk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for taking the time to look into the issue I've created yesterday! 👍

It feels like the implementation might be a bit brittle in regards of some assumptions made on the case-(in)sensitivity comparison of two media type strings? Also, certainly having more data to take into account for matching makes things harder. Having test coverage is great, maybe we can improve/simplify the logic still in some areas?

@yoeunes yoeunes force-pushed the httpfoundation-acceptheader-params branch 6 times, most recently from 9e19845 to bebe53d Compare November 3, 2025 19:36
@yoeunes
Copy link
Contributor Author

yoeunes commented Nov 3, 2025

Hi @andesk, I'm consolidating my responses to your comments here to keep the thread tidy.

Thanks for the detailed review. I've pushed a full refactor that applies your suggestions, makes the code more readable, and adds explanatory comments.

Regarding case-insensitivity, you are correct. I'm now normalizing parameter names using strtolower() when building the canonical key. This aligns with RFC 9110 (Section 5.6.6) and correctly handles duplicates (e.g., Charset vs charset).
https://www.rfc-editor.org/rfc/rfc9110.html#section-5.6.6

The PR should be ready for another look. Thanks!

@yoeunes yoeunes force-pushed the httpfoundation-acceptheader-params branch from bebe53d to c1dee8f Compare November 3, 2025 19:57
Copy link
Member

@derrabus derrabus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for working on this issue.

I think, we should add additional tests for Request::getAcceptableContentTypes() and Request::getPreferredFormat() because they're directly impacted by this change.

@yoeunes yoeunes force-pushed the httpfoundation-acceptheader-params branch 2 times, most recently from 7f880eb to 284531e Compare November 5, 2025 12:57
@yoeunes
Copy link
Contributor Author

yoeunes commented Nov 5, 2025

Hi @derrabus, thank you for your review and feedback!

I've just pushed an update to add the requested tests for Request::getAcceptableContentTypes() and Request::getPreferredFormat(), covering scenarios with parameters, quality sorting, wildcards, case-insensitivity

Let me know if anything else is needed.

@yoeunes yoeunes force-pushed the httpfoundation-acceptheader-params branch from 284531e to 9b1fb5c Compare November 5, 2025 13:28
@yoeunes yoeunes force-pushed the httpfoundation-acceptheader-params branch from 9b1fb5c to 33f535e Compare November 6, 2025 20:06
Copy link
Contributor

@Spomky Spomky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Many thanks!

@nicolas-grekas nicolas-grekas changed the base branch from 7.3 to 6.4 November 12, 2025 16:43
@nicolas-grekas nicolas-grekas force-pushed the httpfoundation-acceptheader-params branch from 53ba9dd to caeb1a0 Compare November 12, 2025 16:58
@nicolas-grekas
Copy link
Member

Thank you @yoeunes.

@nicolas-grekas nicolas-grekas merged commit d286378 into symfony:6.4 Nov 12, 2025
8 of 10 checks passed
@nicolas-grekas
Copy link
Member

This fails on 7.4, with some implicit dependency:

  • fail: ./phpunit src/Symfony/Component/HttpFoundation/
  • pass: ./phpunit src/Symfony/Component/HttpFoundation/ --filter testGetPreferredFormatRfc9110

We missed something.

Could you please have a look @yoeunes?

Not related to the failure, but this would be nicer than an array_map:

--- a/src/Symfony/Component/HttpFoundation/AcceptHeader.php
+++ b/src/Symfony/Component/HttpFoundation/AcceptHeader.php
@@ -48,16 +48,19 @@ class AcceptHeader
     {
         $parts = HeaderUtils::split($headerValue ?? '', ',;=');

-        return new self(array_map(function ($subParts) {
-            static $index = 0;
+        $items = [];
+        $index = 0;
+        foreach ($parts as $subParts) {
             $part = array_shift($subParts);
             $attributes = HeaderUtils::combine($subParts);

             $item = new AcceptHeaderItem($part[0], $attributes);
             $item->setIndex($index++);

-            return $item;
-        }, $parts));
+            $items[] = $item;
+        }
+
+        return new self($items);
     }

@nicolas-grekas
Copy link
Member

FYI I'm having a look at my own previous comment.

nicolas-grekas added a commit that referenced this pull request Nov 13, 2025
…kas)

This PR was merged into the 6.4 branch.

Discussion
----------

[HttpFoundation] Fix RequestTest insulation

| Q             | A
| ------------- | ---
| Branch?       | 6.4
| Bug fix?      | no
| New feature?  | no
| Deprecations? | no
| Issues        | -
| License       | MIT

Missing insulation is how we wrote bad tests in 7.4
Also addressing my patch proposal at
#62287 (comment)

Commits
-------

2d3779a [HttpFoundation] Fix RequestTest insulation
This was referenced Nov 13, 2025
This was referenced Dec 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants