Create a redirect request for a specific request object
Takes into account strict RFC compliant redirection (e.g. redirect POST with POST) vs doing what most clients do (e.g. redirect POST with GET).
RequestInterface $request Request being redirected:
RequestInterface $original Original request:
int $statusCode Status code of the redirect:
string $location Location header of the redirect:
RequestInterface Returns a new redirect request
CouldNotRewindStreamException If the body needs to be rewound but cannot
protected function createRedirectRequest(RequestInterface $request, $statusCode, $location, RequestInterface $original) {
$redirectRequest = null;
$strict = $original
->getParams()
->get(self::STRICT_REDIRECTS);
// Use a GET request if this is an entity enclosing request and we are not forcing RFC compliance, but rather
// emulating what all browsers would do
if ($request instanceof EntityEnclosingRequestInterface && !$strict && $statusCode <= 302) {
$redirectRequest = $this
->cloneRequestWithGetMethod($request);
}
else {
$redirectRequest = clone $request;
}
$location = Url::factory($location);
// If the location is not absolute, then combine it with the original URL
if (!$location
->isAbsolute()) {
$originalUrl = $redirectRequest
->getUrl(true);
// Remove query string parameters and just take what is present on the redirect Location header
$originalUrl
->getQuery()
->clear();
$location = $originalUrl
->combine((string) $location);
}
$redirectRequest
->setUrl($location);
$redirectRequest
->getParams()
->set(self::PARENT_REQUEST, $request);
// Rewind the entity body of the request if needed
if ($redirectRequest instanceof EntityEnclosingRequestInterface && $redirectRequest
->getBody()) {
$body = $redirectRequest
->getBody();
// Only rewind the body if some of it has been read already, and throw an exception if the rewind fails
if ($body
->ftell() && !$body
->rewind()) {
throw new CouldNotRewindStreamException('Unable to rewind the non-seekable entity body of the request after redirecting. cURL probably ' . 'sent part of body before the redirect occurred. Try adding acustom rewind function using on the ' . 'entity body of the request using setRewindFunction().');
}
}
return $redirectRequest;
}