Files
zyt/server/app/common/service/iam/IamHttpClient.php
T

85 lines
2.8 KiB
PHP

<?php
declare(strict_types=1);
namespace app\common\service\iam;
use RuntimeException;
class IamHttpClient
{
/** @var callable|null */
private $transport;
private int $timeoutSeconds;
public function __construct(?callable $transport = null, int $timeoutSeconds = 10)
{
$this->transport = $transport;
$this->timeoutSeconds = $timeoutSeconds;
}
/** @return array{status:int,body:array<string,mixed>} */
public function json(string $method, string $url, array $headers = [], ?array $json = null): array
{
$headers[] = 'Accept: application/json';
$body = null;
if ($json !== null) {
$headers[] = 'Content-Type: application/json';
$body = json_encode($json, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR);
}
return $this->send($method, $url, $headers, $body);
}
/** @return array{status:int,body:array<string,mixed>} */
public function form(string $url, array $form): array
{
return $this->send(
'POST',
$url,
['Accept: application/json', 'Content-Type: application/x-www-form-urlencoded'],
http_build_query($form, '', '&', PHP_QUERY_RFC3986)
);
}
/** @return array{status:int,body:array<string,mixed>} */
private function send(string $method, string $url, array $headers, ?string $body): array
{
if ($this->transport !== null) {
$result = ($this->transport)($method, $url, $headers, $body);
if (!is_array($result) || !isset($result['status'], $result['body'])) {
throw new RuntimeException('IAM HTTP transport returned an invalid response');
}
return $result;
}
$curl = curl_init($url);
if ($curl === false) {
throw new RuntimeException('Unable to initialize IAM HTTP request');
}
curl_setopt_array($curl, [
CURLOPT_CUSTOMREQUEST => strtoupper($method),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_CONNECTTIMEOUT => min(5, $this->timeoutSeconds),
CURLOPT_TIMEOUT => $this->timeoutSeconds,
CURLOPT_HTTPHEADER => $headers,
]);
if ($body !== null) {
curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
}
$raw = curl_exec($curl);
$status = (int) curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
$error = curl_error($curl);
curl_close($curl);
if ($raw === false) {
throw new RuntimeException('IAM HTTP request failed: ' . $error);
}
$decoded = json_decode((string) $raw, true);
return [
'status' => $status,
'body' => is_array($decoded) ? $decoded : [],
];
}
}