opcua-client-ext-transport-https · v4.4.x
Docs · API

HTTP client

HttpClientInterface + CurlHttpClient — the POST-only HTTP backend the transport drives. Replace it to integrate any HTTP stack you prefer.

HttpClientInterface

php 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

php DTOs
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.

php CurlHttpClient constructor
public function __construct(
    bool $verifyTls = true,
    ?string $caBundle = null,
    ?string $clientCertPath = null,
    ?string $clientKeyPath = null,
    ?string $clientKeyPassword = null,
    array $extraCurlOptions = [],
);
Parameters
verifyTls
bool optional default true

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

caBundle
?string optional default null

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

clientCertPath
?string optional default null

Mutual TLS client certificate (PEM file).

clientKeyPath
?string optional default null

Mutual TLS private key (PEM file).

clientKeyPassword
?string optional default null

Optional password for the client private key.

extraCurlOptions
array optional default []

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:

php Psr18HttpClient (sketch)
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 {}
}

Note

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