57 lines
1.9 KiB
PHP
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);
|
|
}
|
|
}
|