|
4 | 4 |
|
5 | 5 | namespace FastForward\Http\Message\Header; |
6 | 6 |
|
7 | | -use function explode; |
8 | | -use function str_contains; |
| 7 | +use function preg_match_all; |
9 | 8 | use function str_ends_with; |
10 | 9 | use function str_starts_with; |
11 | 10 | use function strtok; |
@@ -57,32 +56,28 @@ public static function getBestMatch(string $acceptHeader, array $supportedTypes) |
57 | 56 | private static function parseHeader(string $header): array |
58 | 57 | { |
59 | 58 | $preferences = []; |
60 | | - $parts = explode(',', $header); |
61 | | - |
62 | | - foreach ($parts as $part) { |
63 | | - $params = explode(';', $part); |
64 | | - $type = trim($params[0]); |
65 | | - $q = 1.0; |
66 | | - |
67 | | - if (isset($params[1]) && str_contains($params[1], 'q=')) { |
68 | | - $q = (float) trim(explode('=', $params[1])[1]); |
| 59 | + // Regex to capture type and an optional q-factor, ignoring other parameters. |
| 60 | + $pattern = '/(?<type>[^,;]+)(?:;[^,]*q=(?<q>[0-9.]+))?/'; |
| 61 | + |
| 62 | + if (preg_match_all($pattern, $header, $matches, PREG_SET_ORDER)) { |
| 63 | + foreach ($matches as $match) { |
| 64 | + $type = trim($match['type']); |
| 65 | + $q = isset($match['q']) && $match['q'] !== '' ? (float) $match['q'] : 1.0; |
| 66 | + |
| 67 | + $preferences[] = [ |
| 68 | + 'type' => $type, |
| 69 | + 'q' => $q, |
| 70 | + 'specificity' => self::calculateSpecificity($type), |
| 71 | + ]; |
69 | 72 | } |
70 | | - |
71 | | - $preferences[] = [ |
72 | | - 'type' => $type, |
73 | | - 'q' => $q, |
74 | | - 'specificity' => self::calculateSpecificity($type), |
75 | | - ]; |
76 | 73 | } |
77 | 74 |
|
78 | | - usort($preferences, function ($a, $b) { |
| 75 | + usort($preferences, static function ($a, $b) { |
79 | 76 | if ($a['q'] !== $b['q']) { |
80 | 77 | return $b['q'] <=> $a['q']; // Sort by quality factor descending |
81 | 78 | } |
82 | | - if ($a['specificity'] !== $b['specificity']) { |
83 | | - return $b['specificity'] <=> $a['specificity']; // Then by specificity descending |
84 | | - } |
85 | | - return 0; |
| 79 | + |
| 80 | + return $b['specificity'] <=> $a['specificity']; // Then by specificity descending |
86 | 81 | }); |
87 | 82 |
|
88 | 83 | return $preferences; |
|
0 commit comments