From 190d2d2d9b86b3a8213169cb441f2da619cf8c51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Sun, 7 Sep 2025 11:54:27 +0200 Subject: [PATCH 1/2] Fix header override --- src/Response.php | 26 ++++++++++++++++---------- tests/e2e/ResponseTest.php | 5 +++++ tests/e2e/server.php | 9 +++++++++ 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/Response.php b/src/Response.php index adcfc02..6379cda 100755 --- a/src/Response.php +++ b/src/Response.php @@ -540,9 +540,15 @@ public function enablePayload(): static * * @param string $key * @param string $value + * @param bool $override */ - public function addHeader(string $key, string $value): static + public function addHeader(string $key, string $value, bool $override = false): static { + if ($override) { + $this->headers[$key] = $value; + return $this; + } + if (\array_key_exists($key, $this->headers)) { if (\is_array($this->headers[$key])) { $this->headers[$key][] = $value; @@ -659,7 +665,7 @@ public function send(string $body = ''): void } $serverHeader = $this->headers['Server'] ?? 'Utopia/Http'; - $this->addHeader('Server', $serverHeader); + $this->addHeader('Server', $serverHeader, override: true); $this->appendCookies(); @@ -674,14 +680,14 @@ public function send(string $body = ''): void if ($algorithm) { $body = $algorithm->compress($body); - $this->addHeader('Content-Length', (string) \strlen($body)); - $this->addHeader('Content-Encoding', $algorithm->getContentEncoding()); - $this->addHeader('X-Utopia-Compression', 'true'); - $this->addHeader('Vary', 'Accept-Encoding'); + $this->addHeader('Content-Length', (string) \strlen($body), override: true); + $this->addHeader('Content-Encoding', $algorithm->getContentEncoding(), override: true); + $this->addHeader('X-Utopia-Compression', 'true', override: true); + $this->addHeader('Vary', 'Accept-Encoding', override: true); } } - $this->addHeader('X-Debug-Speed', (string) (microtime(true) - $this->startTime)); + $this->addHeader('X-Debug-Speed', (string) (microtime(true) - $this->startTime), override: true); $this->appendHeaders(); // Send response @@ -769,7 +775,7 @@ public function chunk(string $body = '', bool $end = false): void $this->sent = true; } - $this->addHeader('X-Debug-Speed', (string) (microtime(true) - $this->startTime)); + $this->addHeader('X-Debug-Speed', (string) (microtime(true) - $this->startTime), override: true); $this ->appendCookies() @@ -799,7 +805,7 @@ protected function appendHeaders(): static // Send content type header if (!empty($this->contentType)) { - $this->addHeader('Content-Type', $this->contentType); + $this->addHeader('Content-Type', $this->contentType, override: true); } // Set application headers @@ -908,7 +914,7 @@ public function redirect(string $url, int $statusCode = 301): void } $this - ->addHeader('Location', $url) + ->addHeader('Location', $url, override: true) ->setStatusCode($statusCode) ->send(''); } diff --git a/tests/e2e/ResponseTest.php b/tests/e2e/ResponseTest.php index ccb734b..9db080e 100644 --- a/tests/e2e/ResponseTest.php +++ b/tests/e2e/ResponseTest.php @@ -162,5 +162,10 @@ public function testSetCookie() $this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals('value1', $response['cookies']['key1']); $this->assertEquals('value2', $response['cookies']['key2']); + + $response = $this->client->call(Client::METHOD_GET, '/set-cookie-override'); + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertArrayNotHasKey('key1', $response['cookies']); + $this->assertEquals('value2', $response['cookies']['key2']); } } diff --git a/tests/e2e/server.php b/tests/e2e/server.php index 0a6641a..3cec25d 100644 --- a/tests/e2e/server.php +++ b/tests/e2e/server.php @@ -42,6 +42,15 @@ $response->send('OK'); }); +App::get('/set-cookie-override') + ->inject('request') + ->inject('response') + ->action(function (Request $request, Response $response) { + $response->addHeader('Set-Cookie', 'key1=value1', override: true); + $response->addHeader('Set-Cookie', 'key2=value2', override: true); + $response->send('OK'); + }); + App::get('/chunked') ->inject('response') ->action(function (Response $response) { From f055a719b8e43e10f3dca8e876f7d70974846a2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Ba=C4=8Do?= Date: Sun, 7 Sep 2025 12:04:58 +0200 Subject: [PATCH 2/2] Fix header case sensitivity --- src/Response.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Response.php b/src/Response.php index 6379cda..3f76a86 100755 --- a/src/Response.php +++ b/src/Response.php @@ -669,9 +669,17 @@ public function send(string $body = ''): void $this->appendCookies(); + $hasContentEncoding = false; + foreach ($this->headers as $name => $values) { + if (\strtolower($name) === 'content-encoding') { + $hasContentEncoding = true; + break; + } + } + // Compress body only if all conditions are met: if ( - empty($this->headers['content-encoding']) && + !$hasContentEncoding && !empty($this->acceptEncoding) && $this->isCompressible($this->contentType) && strlen($body) > $this->compressionMinSize