|
@ -14,6 +14,8 @@ use Psr\Http\Client\ClientInterface; |
|
|
|
|
|
|
|
|
class HttpClient implements RequestFactoryInterface, ClientInterface { |
|
|
class HttpClient implements RequestFactoryInterface, ClientInterface { |
|
|
public const ACCEPT_FEED = "application/atom+xml, application/rss+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, */*;q=0.1"; |
|
|
public const ACCEPT_FEED = "application/atom+xml, application/rss+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, */*;q=0.1"; |
|
|
|
|
|
public const ACCEPT_IMAGE = "image/*"; |
|
|
|
|
|
public const ACCEPT_ICON = "image/svg+xml, image/png;q=0.9, image/*;q=0.1"; |
|
|
|
|
|
|
|
|
/** @var string $userAgent The User-Agent to identify as */ |
|
|
/** @var string $userAgent The User-Agent to identify as */ |
|
|
public $userAgent = ""; |
|
|
public $userAgent = ""; |
|
@ -30,6 +32,12 @@ class HttpClient implements RequestFactoryInterface, ClientInterface { |
|
|
$this->requestFactory = $requestFactory; |
|
|
$this->requestFactory = $requestFactory; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** Sends an HTTP request and returns a response |
|
|
|
|
|
* |
|
|
|
|
|
* Redirects are followed up to the configured threshold. If credentials |
|
|
|
|
|
* are supplied in the URL, these only apply to the original request; |
|
|
|
|
|
* credentials are not sent to redirecr URLs, even for the same origin. |
|
|
|
|
|
*/ |
|
|
public function sendRequest(RequestInterface $request): ResponseInterface { |
|
|
public function sendRequest(RequestInterface $request): ResponseInterface { |
|
|
$stop = $this->maxRedirects; |
|
|
$stop = $this->maxRedirects; |
|
|
for ($a = 0; $a <= $stop; $a++) { |
|
|
for ($a = 0; $a <= $stop; $a++) { |
|
@ -42,7 +50,7 @@ class HttpClient implements RequestFactoryInterface, ClientInterface { |
|
|
} else { |
|
|
} else { |
|
|
$loc = $response->getHeader("Location"); |
|
|
$loc = $response->getHeader("Location"); |
|
|
for ($b = 0; $b < sizeof($loc); $b++) { |
|
|
for ($b = 0; $b < sizeof($loc); $b++) { |
|
|
if ($url = Url::fromString($loc[$b], (string) $request->getUri())) { |
|
|
if ($url = Url::fromString($loc[$b], (string) $request->getUri()->withUserInfo("", ""))) { |
|
|
$request = $request->withUri($url); |
|
|
$request = $request->withUri($url); |
|
|
if ($code === 303 && !in_array($request->getMethod(), ["GET", "HEAD"])) { |
|
|
if ($code === 303 && !in_array($request->getMethod(), ["GET", "HEAD"])) { |
|
|
$request = $request->withMethod("GET"); |
|
|
$request = $request->withMethod("GET"); |
|
@ -56,7 +64,40 @@ class HttpClient implements RequestFactoryInterface, ClientInterface { |
|
|
throw new Exception("tooManyRedirects"); |
|
|
throw new Exception("tooManyRedirects"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
public function createRequest(string $method, $uri): RequestInterface { |
|
|
public function createRequest(string $method, $uri, array $headers = []): RequestInterface { |
|
|
return $this->requestFactory->createRequest($method, $uri); |
|
|
$req = $this->requestFactory->createRequest($method, $uri); |
|
|
|
|
|
if (strlen($this->userAgent)) { |
|
|
|
|
|
$req = $req->withHeader("User-Agent", $this->userAgent); |
|
|
|
|
|
} |
|
|
|
|
|
foreach ($headers as $k => $v) { |
|
|
|
|
|
if (!is_array($v)) { |
|
|
|
|
|
$v = [$v]; |
|
|
|
|
|
} else { |
|
|
|
|
|
$v = array_values($v); |
|
|
|
|
|
} |
|
|
|
|
|
foreach ($v as $kk => $vv) { |
|
|
|
|
|
if ($vv instanceof \DateTimeImmutable) { |
|
|
|
|
|
$vv = $vv->setTimezone(new \DateTimeZone("UTC"))->format(\DateTimeInterface::RFC7231); |
|
|
|
|
|
} elseif ($vv instanceof \DateTime) { |
|
|
|
|
|
$vv = clone $vv; |
|
|
|
|
|
$vv->setTimezone(new \DateTimeZone("UTC")); |
|
|
|
|
|
$v = $vv->format(\DateTimeInterface::RFC7231); |
|
|
|
|
|
} |
|
|
|
|
|
$m = $kk === 0 ? "withHeader" : "withAddedHeader"; |
|
|
|
|
|
$req->$m($k, (string) $vv); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
return $req; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public function fetch($uri, string $accept = "*/*", string $etag = "", ?\DateTimeInterface $lastModified = null): ResponseInterface { |
|
|
|
|
|
$headers = ['Accept' => $accept]; |
|
|
|
|
|
if (strlen($etag)) { |
|
|
|
|
|
$headers['ETag'] = $etag; |
|
|
|
|
|
} |
|
|
|
|
|
if ($lastModified) { |
|
|
|
|
|
$headers['Last-Modified'] = $lastModified; |
|
|
|
|
|
} |
|
|
|
|
|
return $this->sendRequest($this->createRequest("GET", $uri, $headers)); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|