All notable changes to this project will be documented in this file.
This project follows semantic versioning.
- Require
utopia-php/psr7^0.2.1soRequest\Factory::multipartalways setsContent-Typewith the body boundary.
- Initial PSR-18 HTTP client wrapper:
Utopia\Client. - Immutable client defaults for headers, base URI, basic auth, and bearer auth.
- cURL adapter for regular PHP runtimes.
- Swoole coroutine adapter for coroutine runtimes.
- Dependency on
utopia-php/psr7forUtopia\Psr7PSR-7 messages and PSR-17 factories. - End-to-end response streaming via
stream(), delivering the body to a sink chunk-by-chunk with bounded memory. Utopia\Psr18\StreamingClientInterfacefor the streaming counterpart to PSR-18; theAdapterinterface composes it withPsr\Http\Client\ClientInterface, andUtopia\ClientimplementsAdapter.- Bounded-memory request uploads on the cURL adapter, streaming the body through a read callback;
Stream\Factory::createStreamFromFile()opens files lazily andStream::fromResource()wraps a resource without copying it. - Bounded-memory multipart file uploads on both adapters via lazy
Part::file()and theMultipart\Bodystream: cURL streams the serialised body from disk, while Swoole streams each file with nativeaddFile()(zero-copysendfile()). - Typed PSR-18 exception hierarchy (
NetworkException/RequestExceptionand their subtypes) thrown by both adapters. - Immutable timeout helpers for total and connection timeouts.
- Portable TLS configuration helpers —
withSslVerification(),withCustomCA(),withCertificate(),withMinTlsVersion()— and theUtopia\Client\Tlsenum. withConnectionReuse()to keep the underlying connection alive and reuse it across requests to the same origin, on both adapters (cURL persists and resets one handle; Swoole keeps a kept-alive coroutine client).withFollowRedirects()to follow HTTPLocationredirects on both adapters (cURL maps toCURLOPT_FOLLOWLOCATION; Swoole followsLocationin the adapter because the coroutine client has no native equivalent). Off by default, so a 3xx response is returned with itsLocationheader. ConstructorCURLOPT_FOLLOWLOCATION/follow_locationvalues do not override the helper. RelativeLocationvalues use RFC 3986 resolution. Cross-origin hops and HTTPS to HTTP downgrades stripAuthorization,Cookie,Cookie2, andProxy-Authorization. Swoole streams the final hop through its write callback rather than buffering it first.Utopia\Client\Poolto borrow a reused client from autopia-php/poolspool per request and reclaim it afterwards, sharing a bounded set of connections across concurrent callers.Utopia\Client\Decorator\Retrydecorator with a pluggableStrategyand a default best-practiceBackoffstrategy (idempotent methods only, transient transport failures and429/502/503/504, exponential backoff with jitter,Retry-Afterhonoured).- Opt-in W3C Trace Context propagation via
withTracePropagation()(off by default): forwards the activeutopia-php/spantrace downstream as atraceparentheader. Utopia\Client\Decoratorbase class for composing adapter decorators.- PHP 8.4+ tooling with Pint, PHPStan level 10, Rector, PHPUnit, Composer audit, and GitHub Actions CI.