Last active
October 4, 2022 18:30
-
-
Save Thinkscape/43499cfafda1af8f606d to your computer and use it in GitHub Desktop.
getEffectiveUrl() replacement for Guzzle 6.*
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
$response->getEffectiveUrl() solution for Guzzle 6 | |
-------------------------------------------------------------- | |
In Guzzle 3, 4 and 5 one could use $response->getEffectiveUrl() to retrieve | |
the last URL in a chain of HTTP redirects. | |
Guzzle 6 uses PSR7 interfaces which do not support this use case, however | |
we can still manipulate response headers to store additional information. | |
This is a standard practice among proxies, caches, authentication gateways | |
and other internet services. | |
The effective URL is stored in response header X-GUZZLE-EFFECTIVE-URL | |
@link http://stackoverflow.com/questions/30682307/how-to-read-the-response-effective-url-in-guzzle-6-0/31962446#31962446 | |
*/ | |
use GuzzleHttp\Client; | |
use Thinkscape\Guzzle\EffectiveUrlMiddleware; | |
// Add the middleware to stack and create guzzle client | |
$stack = HandlerStack::create(); | |
$stack->push(EffectiveUrlMiddleware::middleware()); | |
$client = new Client(['handler' => $stack]); | |
// Test it out! | |
$response = $client->get('http://bit.ly/1N2DZdP'); | |
echo $response->getHeaderLine('X-GUZZLE-EFFECTIVE-URL'); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Thinkscape\Guzzle; | |
use Psr\Http\Message\RequestInterface; | |
use Psr\Http\Message\ResponseInterface; | |
class EffectiveUrlMiddleware | |
{ | |
/** | |
* @var Callable | |
*/ | |
protected $nextHandler; | |
/** | |
* @var string | |
*/ | |
protected $headerName; | |
/** | |
* @param callable $nextHandler | |
* @param string $headerName The header name to use for storing effective url | |
*/ | |
public function __construct( | |
callable $nextHandler, | |
$headerName = 'X-GUZZLE-EFFECTIVE-URL' | |
) { | |
$this->nextHandler = $nextHandler; | |
$this->headerName = $headerName; | |
} | |
/** | |
* Inject effective-url header into response. | |
* | |
* @param RequestInterface $request | |
* @param array $options | |
* | |
* @return RequestInterface | |
*/ | |
public function __invoke(RequestInterface $request, array $options) | |
{ | |
$fn = $this->nextHandler; | |
return $fn($request, $options)->then(function (ResponseInterface $response) use ($request, $options) { | |
return $response->withAddedHeader($this->headerName, $request->getUri()->__toString()); | |
}); | |
} | |
/** | |
* Prepare a middleware closure to be used with HandlerStack | |
* | |
* @param string $headerName The header name to use for storing effective url | |
* | |
* @return \Closure | |
*/ | |
public static function middleware($headerName = 'X-GUZZLE-EFFECTIVE-URL') | |
{ | |
return function (callable $handler) use (&$headerName) { | |
return new static($handler, $headerName); | |
}; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@Thinkscape Have you ever thought of turning this into something that can easily be installed using composer? :)