diff --git a/src/RedirectMiddleware.php b/src/RedirectMiddleware.php index 1dd38614f..89c06526b 100644 --- a/src/RedirectMiddleware.php +++ b/src/RedirectMiddleware.php @@ -88,6 +88,16 @@ public function checkRedirect(RequestInterface $request, array $options, Respons $this->guardMax($request, $response, $options); $nextRequest = $this->modifyRequest($request, $options, $response); + // If authorization is handled by curl, unset it if host is different. + if ($request->getUri()->getHost() !== $nextRequest->getUri()->getHost() + && defined('\CURLOPT_HTTPAUTH') + ) { + unset( + $options['curl'][\CURLOPT_HTTPAUTH], + $options['curl'][\CURLOPT_USERPWD] + ); + } + if (isset($options['allow_redirects']['on_redirect'])) { ($options['allow_redirects']['on_redirect'])( $request, diff --git a/tests/RedirectMiddlewareTest.php b/tests/RedirectMiddlewareTest.php index bc587c0a2..1e0841a27 100644 --- a/tests/RedirectMiddlewareTest.php +++ b/tests/RedirectMiddlewareTest.php @@ -300,6 +300,64 @@ static function (RequestInterface $request) { $client->get('http://example.com?a=b', ['auth' => ['testuser', 'testpass']]); } + /** + * @testWith ["digest"] + * ["ntlm"] + */ + public function testRemoveCurlAuthorizationOptionsOnRedirect($auth) + { + if (!defined('\CURLOPT_HTTPAUTH')) { + self::markTestSkipped('ext-curl is required for this test'); + } + + $mock = new MockHandler([ + new Response(302, ['Location' => 'http://test.com']), + static function (RequestInterface $request, $options) { + self::assertFalse( + isset($options['curl'][\CURLOPT_HTTPAUTH]), + 'curl options still contain CURLOPT_HTTPAUTH entry' + ); + self::assertFalse( + isset($options['curl'][\CURLOPT_USERPWD]), + 'curl options still contain CURLOPT_USERPWD entry' + ); + return new Response(200); + } + ]); + $handler = HandlerStack::create($mock); + $client = new Client(['handler' => $handler]); + $client->get('http://example.com?a=b', ['auth' => ['testuser', 'testpass', $auth]]); + } + + /** + * @testWith ["digest"] + * ["ntlm"] + */ + public function testNotRemoveCurlAuthorizationOptionsOnRedirect($auth) + { + if (!defined('\CURLOPT_HTTPAUTH') || !defined('\CURLOPT_USERPWD')) { + self::markTestSkipped('ext-curl is required for this test'); + } + + $mock = new MockHandler([ + new Response(302, ['Location' => 'http://example.com/2']), + static function (RequestInterface $request, $options) { + self::assertTrue( + isset($options['curl'][\CURLOPT_HTTPAUTH]), + 'curl options does not contain expected CURLOPT_HTTPAUTH entry' + ); + self::assertTrue( + isset($options['curl'][\CURLOPT_USERPWD]), + 'curl options does not contain expected CURLOPT_USERPWD entry' + ); + return new Response(200); + } + ]); + $handler = HandlerStack::create($mock); + $client = new Client(['handler' => $handler]); + $client->get('http://example.com?a=b', ['auth' => ['testuser', 'testpass', $auth]]); + } + /** * Verifies how RedirectMiddleware::modifyRequest() modifies the method and body of a request issued when * encountering a redirect response.