diff --git a/src/RequestResolver.php b/src/RequestResolver.php index 41cbdfa..498298a 100644 --- a/src/RequestResolver.php +++ b/src/RequestResolver.php @@ -180,6 +180,12 @@ private function writeHeader( $i = $this->getIndex($ch); $headerLine = trim($rawHeader); + if($this->isStartOfNewHeaderBlock($i, $headerLine)) { + $this->headerList[$i] = ""; + $this->responseList[$i] = new Response(); + $this->responseList[$i]->startDeferredResponse($this->curlList[$i]); + } + // If $headerLine is empty, it represents the last line before the body starts. // HTTP headers always end on an empty line. // See https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html @@ -218,6 +224,11 @@ private function writeHeader( return strlen($rawHeader); } + private function isStartOfNewHeaderBlock(int $index, string $headerLine):bool { + return str_starts_with(strtolower($headerLine), "http/") + && trim($this->headerList[$index]) !== ""; + } + private function writeBody(CurlHandle|CurlInterface $ch, string $content):int { $i = $this->getIndex($ch); diff --git a/test/phpunit/Helper/ResponseSimulator.php b/test/phpunit/Helper/ResponseSimulator.php index a02719d..046b4c5 100644 --- a/test/phpunit/Helper/ResponseSimulator.php +++ b/test/phpunit/Helper/ResponseSimulator.php @@ -75,8 +75,21 @@ static public function hasStarted():bool { } static public function sendChunk(CurlInterface $ch):int { -// TODO: If the URL is test://should-redirect, send the redirect header here $url = $ch->getInfo(CURLINFO_EFFECTIVE_URL); + if($url === "test://should-follow-redirect" && !self::$redirectAdded) { + self::$headerBuffer = [ + "HTTP/1.1 303 See Other\r\n", + "Content-Type: text/html\r\n", + "Location: /redirected\r\n", + "\r\n", + "HTTP/1.1 200 OK\r\n", + "Content-Type: application/json\r\n", + "X-Final-Response: true\r\n", + "\r\n", + ]; + self::$bodyBuffer = "{}"; + self::$redirectAdded = true; + } if($url === "test://should-redirect") { $locationRedirect = "Location: /redirected\r\n"; if(!self::$redirectAdded) { diff --git a/test/phpunit/HttpTest.php b/test/phpunit/HttpTest.php index d789886..8f53ced 100644 --- a/test/phpunit/HttpTest.php +++ b/test/phpunit/HttpTest.php @@ -148,6 +148,23 @@ public function testFetchRedirectError():void { self::assertInstanceOf(FetchException::class, $actualRejection); } + /** @runInSeparateProcess */ + public function testFollowedRedirectOnlyExposesFinalResponseHeaders():void { + $sut = new Http( + [], + 0.01, + TestCurl::class, + TestCurlMulti::class + ); + + $response = $sut->awaitFetch("test://should-follow-redirect"); + + self::assertSame(200, $response->status); + self::assertSame("application/json", $response->getHeaderLine("Content-Type")); + self::assertSame("true", $response->getHeaderLine("X-Final-Response")); + self::assertSame("", $response->getHeaderLine("Location")); + } + /** @runInSeparateProcess */ public function testAwaitFetch():void { $http = new Http(