From cdf125995da510f917574ec8897929627e4ee33c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Sat, 6 Apr 2024 17:06:53 +0200 Subject: [PATCH 1/2] Update to reactphp/http `v1.10.0` and update SAPI tests --- composer.json | 2 +- tests/Io/SapiHandlerTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index e41dcb5..290d2bb 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ "php": ">=7.1", "nikic/fast-route": "^1.3", "react/async": "^4 || ^3", - "react/http": "^1.9", + "react/http": "^1.10", "react/promise": "^3 || ^2.10", "react/socket": "^1.13" }, diff --git a/tests/Io/SapiHandlerTest.php b/tests/Io/SapiHandlerTest.php index 912d46d..840afc7 100644 --- a/tests/Io/SapiHandlerTest.php +++ b/tests/Io/SapiHandlerTest.php @@ -133,7 +133,7 @@ public function testRequestFromGlobalsWithConnectProxy(): void $request = $sapi->requestFromGlobals(); $this->assertEquals('CONNECT', $request->getMethod()); - $this->assertEquals('example.com:443', (string) $request->getUri()); + $this->assertEquals('//example.com:443', (string) $request->getUri()); $this->assertEquals('example.com:443', $request->getRequestTarget()); $this->assertEquals('1.1', $request->getProtocolVersion()); $this->assertEquals('example.com:443', $request->getHeaderLine('Host')); From 2b2c4996e29a911b1f31c5aa2454f2dc955942a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20L=C3=BCck?= Date: Fri, 12 Apr 2024 22:04:13 +0200 Subject: [PATCH 2/2] Consistent parsing for HTTP `CONNECT` request method (PHP SAPI) --- src/Io/SapiHandler.php | 2 ++ tests/Io/SapiHandlerTest.php | 62 +++++++++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/Io/SapiHandler.php b/src/Io/SapiHandler.php index d3faf27..fc2eeb1 100644 --- a/src/Io/SapiHandler.php +++ b/src/Io/SapiHandler.php @@ -69,6 +69,8 @@ public function requestFromGlobals(): ServerRequestInterface $url = $target; if (($target[0] ?? '/') === '/' || $target === '*') { $url = (($_SERVER['HTTPS'] ?? null) === 'on' ? 'https://' : 'http://') . ($host ?? 'localhost') . ($target === '*' ? '' : $target); + } elseif (($_SERVER['REQUEST_METHOD'] ?? null) === 'CONNECT') { + $url = (($_SERVER['HTTPS'] ?? null) === 'on' ? 'https://' : 'http://') . $target; } $body = file_get_contents('php://input'); diff --git a/tests/Io/SapiHandlerTest.php b/tests/Io/SapiHandlerTest.php index 840afc7..a18b390 100644 --- a/tests/Io/SapiHandlerTest.php +++ b/tests/Io/SapiHandlerTest.php @@ -133,7 +133,67 @@ public function testRequestFromGlobalsWithConnectProxy(): void $request = $sapi->requestFromGlobals(); $this->assertEquals('CONNECT', $request->getMethod()); - $this->assertEquals('//example.com:443', (string) $request->getUri()); + $this->assertEquals('http://example.com:443', (string) $request->getUri()); + $this->assertEquals('example.com:443', $request->getRequestTarget()); + $this->assertEquals('1.1', $request->getProtocolVersion()); + $this->assertEquals('example.com:443', $request->getHeaderLine('Host')); + } + + /** + * @backupGlobals enabled + */ + public function testRequestFromGlobalsWithConnectProxyWithDefaultHttpPort(): void + { + $_SERVER['REQUEST_METHOD'] = 'CONNECT'; + $_SERVER['REQUEST_URI'] = 'example.com:80'; + $_SERVER['SERVER_PROTOCOL'] = 'http/1.1'; + $_SERVER['HTTP_HOST'] = 'example.com'; + + $sapi = new SapiHandler(); + $request = $sapi->requestFromGlobals(); + + $this->assertEquals('CONNECT', $request->getMethod()); + $this->assertEquals('http://example.com', (string) $request->getUri()); + $this->assertEquals('example.com:80', $request->getRequestTarget()); + $this->assertEquals('1.1', $request->getProtocolVersion()); + $this->assertEquals('example.com', $request->getHeaderLine('Host')); + } + + /** + * @backupGlobals enabled + */ + public function testRequestFromGlobalsWithConnectProxyWithoutHostHeader(): void + { + $_SERVER['REQUEST_METHOD'] = 'CONNECT'; + $_SERVER['REQUEST_URI'] = 'example.com:8080'; + $_SERVER['SERVER_PROTOCOL'] = 'http/1.1'; + + $sapi = new SapiHandler(); + $request = $sapi->requestFromGlobals(); + + $this->assertEquals('CONNECT', $request->getMethod()); + $this->assertEquals('http://example.com:8080', (string) $request->getUri()); + $this->assertEquals('example.com:8080', $request->getRequestTarget()); + $this->assertEquals('1.1', $request->getProtocolVersion()); + $this->assertFalse($request->hasHeader('Host')); + } + + /** + * @backupGlobals enabled + */ + public function testRequestFromGlobalsWithConnectProxyOverHttps(): void + { + $_SERVER['REQUEST_METHOD'] = 'CONNECT'; + $_SERVER['REQUEST_URI'] = 'example.com:443'; + $_SERVER['SERVER_PROTOCOL'] = 'http/1.1'; + $_SERVER['HTTP_HOST'] = 'example.com:443'; + $_SERVER['HTTPS'] = 'on'; + + $sapi = new SapiHandler(); + $request = $sapi->requestFromGlobals(); + + $this->assertEquals('CONNECT', $request->getMethod()); + $this->assertEquals('https://example.com', (string) $request->getUri()); $this->assertEquals('example.com:443', $request->getRequestTarget()); $this->assertEquals('1.1', $request->getProtocolVersion()); $this->assertEquals('example.com:443', $request->getHeaderLine('Host'));