Skip to content

Latest commit

 

History

History
157 lines (132 loc) · 4.98 KB

File metadata and controls

157 lines (132 loc) · 4.98 KB
eyebrow Docs · API
lede HttpClientInterface + CurlHttpClient — the POST-only HTTP backend the transport drives. Replace it to integrate any HTTP stack you prefer.
see_also
href meta
./transport.md
4 min
href meta
../recipes/tls-and-cert-trust.md
3 min
href meta
../recipes/corporate-proxy.md
3 min
prev
label href
Encoding strategies
./encoding-strategies.md
next
label href
Events
./events.md

HTTP client

HttpClientInterface

namespace PhpOpcua\Client\ExtTransportHttps\Http;

interface HttpClientInterface
{
    public function post(HttpRequest $request, float $timeoutSeconds): HttpResponse;

    public function close(): void;
}

Minimal on purpose — OPC UA Part 6 §7.4 uses POST exclusively. Throws HttpsRequestException on network / TLS / connect failures (no response). Non-2xx responses come back through HttpResponse; the transport turns them into HttpsStatusException.

HttpRequest / HttpResponse

final readonly class HttpRequest
{
    public function __construct(
        public string $url,
        public string $body,
        public string $contentType,
        public string $acceptHeader,
        public array $extraHeaders = [],   // header-name => value
    );
}

final readonly class HttpResponse
{
    public function __construct(
        public int $statusCode,
        public string $body,
        public array $headers = [],        // lower-cased header-name => value
    );

    public function isSuccessful(): bool;  // 200..299
}

CurlHttpClient

Default backend, backed by ext-curl. Keeps a single cURL handle across requests so HTTP keep-alive and TLS session resumption work out of the box; the handle is released by close() or destruction.

public function __construct(
    bool $verifyTls = true,
    ?string $caBundle = null,
    ?string $clientCertPath = null,
    ?string $clientKeyPath = null,
    ?string $clientKeyPassword = null,
    array $extraCurlOptions = [],
);

When true, verify the server certificate chain and hostname. Disable only in controlled test environments.

Optional CA bundle path. When null, cURL uses the system CA store.

Mutual TLS client certificate (PEM file).

Mutual TLS private key (PEM file).

Optional password for the client private key.

CURLOPT_* array merged after the defaults. Use for proxy settings, custom User-Agent, debug verbosity, etc.

TLS defaults

The client uses cURL's own defaults: TLS 1.2+ negotiation, modern cipher suites. To pin a specific TLS version, pass [CURLOPT_SSLVERSION => CURL_SSLVERSION_TLSv1_3] through $extraCurlOptions.

Bring your own client

Any class implementing HttpClientInterface works. A thin wrapper over PSR-18 is roughly:

use Psr\Http\Client\ClientInterface as Psr18Client;
use Psr\Http\Message\RequestFactoryInterface;
use Psr\Http\Message\StreamFactoryInterface;

final class Psr18HttpClient implements HttpClientInterface
{
    public function __construct(
        private readonly Psr18Client $client,
        private readonly RequestFactoryInterface $requests,
        private readonly StreamFactoryInterface $streams,
    ) {}

    public function post(HttpRequest $request, float $timeoutSeconds): HttpResponse
    {
        $r = $this->requests->createRequest('POST', $request->url)
            ->withHeader('Content-Type', $request->contentType)
            ->withHeader('Accept', $request->acceptHeader)
            ->withBody($this->streams->createStream($request->body));
        foreach ($request->extraHeaders as $n => $v) {
            $r = $r->withHeader($n, $v);
        }
        try {
            $r2 = $this->client->sendRequest($r);
        } catch (\Throwable $e) {
            throw new HttpsRequestException('PSR-18 request failed: ' . $e->getMessage(), 0, $e);
        }
        return new HttpResponse($r2->getStatusCode(), (string) $r2->getBody());
    }

    public function close(): void {}
}

A ready-made Psr18HttpClient may ship in a later minor — open an issue if you want it sooner.