/** * Sends a request to a HTTP server, and returns a response. * * @param RequestInterface $request * @return ResponseInterface */ function send(RequestInterface $request) { $this->emit('beforeRequest', [$request]); $retryCount = 0; $redirects = 0; do { $doRedirect = false; $retry = false; try { $response = $this->doRequest($request); $code = (int) $response->getStatus(); // We are doing in-PHP redirects, because curl's // FOLLOW_LOCATION throws errors when PHP is configured with // open_basedir. // // https://github.com/fruux/sabre-http/issues/12 if (in_array($code, [301, 302, 307, 308]) && $redirects < $this->maxRedirects) { $oldLocation = $request->getUrl(); // Creating a new instance of the request object. $request = clone $request; // Setting the new location $request->setUrl(URLUtil::resolve($oldLocation, $response->getHeader('Location'))); $doRedirect = true; $redirects++; } // This was a HTTP error if ($code >= 400) { $this->emit('error', [$request, $response, &$retry, $retryCount]); $this->emit('error:' . $code, [$request, $response, &$retry, $retryCount]); } } catch (ClientException $e) { $this->emit('exception', [$request, $e, &$retry, $retryCount]); // If retry was still set to false, it means no event handler // dealt with the problem. In this case we just re-throw the // exception. if (!$retry) { throw $e; } } if ($retry) { $retryCount++; } } while ($retry || $doRedirect); $this->emit('afterRequest', [$request, $response]); if ($this->throwExceptions && $code >= 400) { throw new ClientHttpException($response); } return $response; }