diff --git a/src/Event/Http/HttpRequestEvent.php b/src/Event/Http/HttpRequestEvent.php index 89e1c2552..ce59eff7f 100644 --- a/src/Event/Http/HttpRequestEvent.php +++ b/src/Event/Http/HttpRequestEvent.php @@ -101,13 +101,13 @@ public function getRemotePort(): int */ public function getBasicAuthCredentials(): array { - $authorizationHeader = trim($this->headers['authorization'][0] ?? ''); + $authorizationHeader = trim($this->headers['authorization'][0] ?? '', " \t"); if (! str_starts_with($authorizationHeader, 'Basic ')) { return [null, null]; } - $auth = base64_decode(trim(explode(' ', $authorizationHeader)[1]), true); + $auth = base64_decode(trim(explode(' ', $authorizationHeader)[1], " \t"), true); if ($auth === false || ! str_contains($auth, ':')) { return [null, null]; @@ -186,7 +186,7 @@ public function getCookies(): array // Multiple "Cookie" headers are not authorized // https://stackoverflow.com/questions/16305814/are-multiple-cookie-headers-allowed-in-an-http-request $cookieHeader = $this->headers['cookie'][0]; - $cookieParts = array_map('trim', explode(';', $cookieHeader)); + $cookieParts = array_map(fn (string $part) => trim($part, " \t"), explode(';', $cookieHeader)); } $cookies = []; diff --git a/src/Runtime/LambdaRuntime.php b/src/Runtime/LambdaRuntime.php index a5e5d88ae..4243cac41 100755 --- a/src/Runtime/LambdaRuntime.php +++ b/src/Runtime/LambdaRuntime.php @@ -149,7 +149,7 @@ private function waitNextInvocation(): array } [$name, $value] = preg_split('/:\s*/', $header, 2); $name = strtolower($name); - $value = trim($value); + $value = trim($value, " \t\r\n"); if ($name === 'lambda-runtime-aws-request-id') { $contextBuilder->setAwsRequestId($value); } diff --git a/tests/Event/Http/HttpRequestEventTest.php b/tests/Event/Http/HttpRequestEventTest.php index 12b478d51..140cbc966 100644 --- a/tests/Event/Http/HttpRequestEventTest.php +++ b/tests/Event/Http/HttpRequestEventTest.php @@ -170,6 +170,18 @@ public function test basic auth with an empty password() $this->assertSame(['user', ''], $event->getBasicAuthCredentials()); } + public function test basic auth with whitespace around the header value() + { + $event = new HttpRequestEvent([ + 'httpMethod' => 'GET', + 'headers' => [ + 'Authorization' => "\t Basic " . base64_encode('user:password') . " \t", + ], + ]); + + $this->assertSame(['user', 'password'], $event->getBasicAuthCredentials()); + } + public function test basic auth without a colon is rejected() { $event = new HttpRequestEvent([ @@ -204,6 +216,18 @@ public function test cookies without a space after the semicolon() $this->assertSame(['a' => '1', 'b' => '2', 'c' => '3'], $event->getCookies()); } + public function test cookies with whitespace around the pairs() + { + $event = new HttpRequestEvent([ + 'httpMethod' => 'GET', + 'headers' => [ + 'Cookie' => "a=1 ;\tb=2\t; c=3", + ], + ]); + + $this->assertSame(['a' => '1', 'b' => '2', 'c' => '3'], $event->getCookies()); + } + /** * @dataProvider provide query strings */ diff --git a/tests/Sam/PhpRuntimeTest.php b/tests/Sam/PhpRuntimeTest.php index bbd379463..9bfcee9af 100644 --- a/tests/Sam/PhpRuntimeTest.php +++ b/tests/Sam/PhpRuntimeTest.php @@ -258,7 +258,7 @@ private function invokeLambda($event = null): array $stderr = preg_replace('/\x1b\[[0-9;]*m/', '', $stderr); // Extract the result from stdout - $output = explode("\n", trim($process->getOutput())); + $output = explode("\n", trim($process->getOutput(), " \t\n\r\0\x0B")); $lastLine = end($output); if (! empty($lastLine)) { $result = json_decode($lastLine, true, 512, JSON_THROW_ON_ERROR); @@ -269,7 +269,7 @@ private function invokeLambda($event = null): array $result = null; // Was there an error? preg_match('/REPORT RequestId: [^\n]*(.*)/s', $stderr, $matches); - $error = trim($matches[1] ?? ''); + $error = trim($matches[1] ?? '', " \t\n\r\0\x0B"); if ($error !== '') { $result = json_decode($error, true, 512, JSON_THROW_ON_ERROR); if (json_last_error()) { @@ -314,7 +314,7 @@ private function assertErrorInLogs( // Extract the only interesting log line $logLines = explode("\n", $logs); $logLines = array_filter($logLines, function (string $line): bool { - $line = trim($line); + $line = trim($line, " \t\n\r\0\x0B"); return $line !== '' && (strpos($line, 'START') !== 0) && (strpos($line, 'END') !== 0)