Files
weerscherm/src/Http.php
T

57 lines
1.9 KiB
PHP

<?php
declare(strict_types=1);
namespace Weerscherm;
/** Dunne curl-wrapper met korte timeouts. Netwerkfouten worden UpstreamException. */
final class Http implements HttpClient
{
public function __construct(private readonly int $timeout = 8, private readonly int $connectTimeout = 5)
{
}
public function get(string $url, array $query = [], array $headers = []): HttpResponse
{
if ($query !== []) {
$url .= (str_contains($url, '?') ? '&' : '?') . http_build_query($query);
}
return $this->request($url, $headers, null);
}
public function postForm(string $url, array $fields): HttpResponse
{
return $this->request($url, ['Content-Type: application/x-www-form-urlencoded'], http_build_query($fields));
}
/** @param list<string> $headers */
private function request(string $url, array $headers, ?string $postBody): HttpResponse
{
$ch = curl_init($url);
if ($ch === false) {
throw new UpstreamException('curl_init mislukt');
}
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_CONNECTTIMEOUT => $this->connectTimeout,
CURLOPT_TIMEOUT => $this->timeout,
CURLOPT_HTTPHEADER => array_merge(['Accept: application/json', 'User-Agent: weerscherm/1.0'], $headers),
CURLOPT_SSL_VERIFYPEER => true,
]);
if ($postBody !== null) {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postBody);
}
$body = curl_exec($ch);
$status = (int) curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
$error = curl_error($ch);
curl_close($ch);
if (!is_string($body)) {
throw new UpstreamException("Verzoek mislukt: $error");
}
return new HttpResponse($status, $body);
}
}