Skip to content

Commit 8657cd6

Browse files
committed
Response::getHeaders() returns array [name => [headers]] instead of [name => header] (BC break!)
1 parent 0022dc0 commit 8657cd6

10 files changed

+23
-21
lines changed

src/Http/IResponse.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ function getHeader(string $header): ?string;
193193

194194
/**
195195
* Returns a associative array of headers to sent.
196+
* @return string[][]
196197
*/
197198
function getHeaders(): array;
198199

src/Http/Response.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,13 +200,14 @@ public function getHeader(string $header): ?string
200200

201201
/**
202202
* Returns a associative array of headers to sent.
203+
* @return string[][]
203204
*/
204205
public function getHeaders(): array
205206
{
206207
$headers = [];
207208
foreach (headers_list() as $header) {
208-
$a = strpos($header, ':');
209-
$headers[substr($header, 0, $a)] = (string) substr($header, $a + 2);
209+
$pair = explode(': ', $header);
210+
$headers[$pair[0]][] = $pair[1];
210211
}
211212
return $headers;
212213
}

tests/Http.DI/HttpExtension.csp.phpt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ Assert::contains("Content-Security-Policy-Report-Only: default-src 'nonce-$nonce
5555

5656
$headers = $container->getByType(Nette\Http\Response::class)->getHeaders();
5757

58-
preg_match('#nonce-([\w+/]+=*)#', implode($headers), $nonce);
59-
Assert::same("default-src 'self' https://example.com; upgrade-insecure-requests; script-src 'nonce-$nonce[1]'; style-src 'self' https://example.com; require-sri-for style; sandbox allow-forms; plugin-types application/x-java-applet;", $headers['Content-Security-Policy']);
60-
Assert::same("default-src 'nonce-$nonce[1]'; report-uri https://example.com/report; upgrade-insecure-requests;", $headers['Content-Security-Policy-Report-Only']);
58+
preg_match('#nonce-([\w+/]+=*)#', implode($headers['Content-Security-Policy']), $nonce);
59+
Assert::same(["default-src 'self' https://example.com; upgrade-insecure-requests; script-src 'nonce-$nonce[1]'; style-src 'self' https://example.com; require-sri-for style; sandbox allow-forms; plugin-types application/x-java-applet;"], $headers['Content-Security-Policy']);
60+
Assert::same(["default-src 'nonce-$nonce[1]'; report-uri https://example.com/report; upgrade-insecure-requests;"], $headers['Content-Security-Policy-Report-Only']);
6161

6262

6363
echo ' '; @ob_flush(); flush();

tests/Http.DI/HttpExtension.featurePolicy.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ Assert::contains("Feature-Policy: unsized-media 'none'; geolocation 'self' https
4343

4444
$headers = $container->getByType(Nette\Http\Response::class)->getHeaders();
4545

46-
Assert::same("unsized-media 'none'; geolocation 'self' https://example.com; camera *;", $headers['Feature-Policy']);
46+
Assert::same(["unsized-media 'none'; geolocation 'self' https://example.com; camera *;"], $headers['Feature-Policy']);
4747

4848

4949
echo ' '; @ob_flush(); flush();

tests/Http.DI/HttpExtension.headers.phpt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,11 @@ Assert::contains('D: 0', $headers);
4444
Assert::notContains('C:', $headers);
4545

4646
$headers = $container->getByType(Nette\Http\Response::class)->getHeaders();
47-
Assert::same('SAMEORIGIN', $headers['X-Frame-Options']);
48-
Assert::same('text/html; charset=utf-8', $headers['Content-Type']);
49-
Assert::same('Nette Framework 3', $headers['X-Powered-By']);
50-
Assert::same('b', $headers['A']);
51-
Assert::same('0', $headers['D']);
47+
Assert::same(['SAMEORIGIN'], $headers['X-Frame-Options']);
48+
Assert::same(['text/html; charset=utf-8'], $headers['Content-Type']);
49+
Assert::same(['Nette Framework 3'], $headers['X-Powered-By']);
50+
Assert::same(['b'], $headers['A']);
51+
Assert::same(['0'], $headers['D']);
5252
Assert::false(isset($headers['C']));
5353

5454

tests/Http.DI/HttpExtension.sameSiteProtection.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Assert::contains(
3434
$headers = $container->getByType(Nette\Http\Response::class)->getHeaders();
3535
Assert::same(
3636
PHP_VERSION_ID >= 70300
37-
? 'nette-samesite=1; path=/; HttpOnly; SameSite=Strict'
38-
: 'nette-samesite=1; path=/; SameSite=Strict; HttpOnly',
37+
? ['nette-samesite=1; path=/; HttpOnly; SameSite=Strict']
38+
: ['nette-samesite=1; path=/; SameSite=Strict; HttpOnly'],
3939
$headers['Set-Cookie']
4040
);

tests/Http/Response.setCookie.phpt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Assert::same([
2727
'Set-Cookie: test=value; path=/; HttpOnly',
2828
], $headers);
2929
Assert::same([
30-
'Set-Cookie' => 'test=value; path=/; HttpOnly',
30+
'Set-Cookie' => ['test=value; path=/; HttpOnly'],
3131
], array_diff_key($response->getHeaders(), $old2));
3232

3333

@@ -38,7 +38,7 @@ Assert::same([
3838
'Set-Cookie: test=newvalue; path=/; HttpOnly',
3939
], $headers);
4040
Assert::same([
41-
'Set-Cookie' => 'test=newvalue; path=/; HttpOnly',
41+
'Set-Cookie' => ['test=value; path=/; HttpOnly', 'test=newvalue; path=/; HttpOnly'],
4242
], array_diff_key($response->getHeaders(), $old2));
4343

4444

@@ -53,6 +53,6 @@ Assert::same([
5353
], $headers);
5454
Assert::same([
5555
'Set-Cookie' => PHP_VERSION_ID >= 70300
56-
? 'test=newvalue; path=/; HttpOnly; SameSite=Lax'
57-
: 'test=newvalue; path=/; SameSite=Lax; HttpOnly',
56+
? ['test=value; path=/; HttpOnly', 'test=newvalue; path=/; HttpOnly', 'test=newvalue; path=/; HttpOnly; SameSite=Lax']
57+
: ['test=value; path=/; HttpOnly', 'test=newvalue; path=/; HttpOnly', 'test=newvalue; path=/; SameSite=Lax; HttpOnly'],
5858
], array_diff_key($response->getHeaders(), $old2));

tests/Http/Session.id.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,4 @@ $session->close();
3434
Assert::true(file_exists(getTempDir() . '/sess_' . $sessionId));
3535
Assert::count(1, glob(getTempDir() . '/sess_*'));
3636

37-
Assert::same('PHPSESSID=' . $sessionId . '; path=/; HttpOnly', $response->getHeaders()['Set-Cookie']);
37+
Assert::same(['PHPSESSID=' . $sessionId . '; path=/; HttpOnly'], $response->getHeaders()['Set-Cookie']);

tests/Http/Session.regenerateId().phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,4 @@ Assert::true(is_file($path . $newId));
3232
$ref = 20;
3333
Assert::same(20, $_SESSION['var']);
3434

35-
Assert::same('PHPSESSID=' . $newId . '; path=/; HttpOnly', $response->getHeaders()['Set-Cookie']);
35+
Assert::same(['PHPSESSID=' . $newId . '; path=/; HttpOnly'], $response->getHeaders()['Set-Cookie']);

tests/Http/Session.sameSite.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Assert::contains(
3030
);
3131
Assert::same(
3232
PHP_VERSION_ID >= 70300
33-
? 'PHPSESSID=' . $session->getId() . '; path=/; HttpOnly; SameSite=Lax'
34-
: 'PHPSESSID=' . $session->getId() . '; path=/; SameSite=Lax; HttpOnly',
33+
? ['PHPSESSID=' . $session->getId() . '; path=/; HttpOnly; SameSite=Lax']
34+
: ['PHPSESSID=' . $session->getId() . '; path=/; SameSite=Lax; HttpOnly'],
3535
$response->getHeaders()['Set-Cookie']
3636
);

0 commit comments

Comments
 (0)