packagist azjezz/psl 6.2.0
Hevlaska 6.2.0

latest releases: 6.1.2, 6.2.1
8 hours ago

PSL 6.2.0

A massive release — three new networking stack components (HTTP, SMTP, DNS), the EitherOrBoth type with full-outer-join iterators, a major IO toolkit expansion, and broad covariance improvements across the type system.

New Components

HTTP Stack

  • HTTP\Message — version-agnostic HTTP message abstractions. Request/Response value objects with streaming bodies (ReadHandleInterface), FieldMap (ordered, case-insensitive headers with lazy index), ProtocolVersion covering HTTP/1.0 through HTTP/3, trailers as Async\Awaitable<FieldMap>, status/method constants per RFC 9110, and Transaction/Exchange for informational (1xx) responses and HTTP/2 server-push pairs.
  • HTTP\Client — async HTTP/1.1 and HTTP/2 client with automatic protocol negotiation via ALPN. Connection pooling (H1 idle reuse, H2 session sharing across concurrent requests), event-driven stream dispatch, transparent reconnection on GOAWAY/TCP reset, RedirectClient and RetryClient decorators, per-request SendConfiguration, SSRF protection via DeniedDestinationsMiddleware, SOCKS5 proxy and HTTP CONNECT tunnel support, H2 flow control with BDP auto-tuning, and 104 integration tests against httpbun.

Mail Stack

  • MIME — comprehensive RFC 2045–2049 toolkit. Media type parsing and content negotiation, MIME part construction with automatic transfer encoding, streaming multipart bodies and parsing (alternative, related, form, generic), Content-Disposition with safe filename extraction, RFC 2231 parameter encoding with continuations and charset conversion, content sniffing from bytes or seekable handles, S/MIME signing/verification/encryption/decryption per RFC 5652/8551, and DKIM signing with RSA-SHA256 and Ed25519-SHA256 per RFC 6376/8463.
  • Message — RFC 5322 internet message construction, parsing, and serialization. Typed header fields with fluent with*() mutation, address methods accepting string|Mailbox|AddressList, streaming serialize()/parse(), reply/reply-all/forward with automatic threading headers, RFC 5321 SMTP envelope derivation, and full RFC 5322 address parsing including RFC 2047 encoded-word support.
  • SMTP — RFC 5321 SMTP client with connection pooling. Low-level Connection for protocol-level operations and high-level Transport managing the full lifecycle (EHLO/HELO, STARTTLS, AUTH, send, RSET). Implicit TLS on port 465 and STARTTLS upgrade with automatic detection, SMTP pipelining (RFC 2920), BDAT chunking (RFC 3030), DSN (RFC 3461), REQUIRETLS (RFC 8689), MT-PRIORITY (RFC 6710), DELIVERBY (RFC 2852), FUTURERELEASE (RFC 4865), BINARYMIME/8BITMIME/SMTPUTF8 negotiation, IDN punycode for international addresses, partial recipient success tracking, CRLF/null byte injection protection, and five authentication mechanisms: PLAIN, LOGIN, XOAUTH2, CRAM-MD5, SCRAM-SHA-256.

DNS Stack

  • DNS — async DNS resolution with full protocol support. SystemResolver mirrors OS DNS behavior; UDP and pooled TCP resolvers with automatic TCP fallback on truncation; DNS-over-TLS (DoT) and DNS-over-HTTPS (DoH, RFC 8484). RacingResolver races multiple nameservers concurrently, SplitHorizonResolver routes by domain, SearchDomainResolver expands short names, HostsFileResolver checks the OS hosts file, CachedResolver decorator with TTL-aware caching, and StaticResolver for tests. Cross-platform system configuration loading on Linux, macOS, and Windows. EDNS0 extensions (cookies, client subnet, padding, NSID, keepalive). 20+ record types covering A, AAAA, NS, CNAME, MX, TXT, SRV, SOA, PTR, CAA, SSHFP, TLSA, SVCB, HTTPS, LOC, NAPTR, DS, DNSKEY, RRSIG, NSEC, NSEC3.
  • DNSSEC — full DNSSEC validation chain. SecureResolver validates RRSIG signatures, TrustChainResolver walks DS/DNSKEY from root to target zone, CachedTrustChainResolver for performance, StaticTrustChainResolver for offline use. NSEC and NSEC3 authenticated denial of existence proofs. Seven signature algorithms: RSA/SHA-1, RSA/SHA-256, RSA/SHA-512, ECDSA P-256, ECDSA P-384, Ed25519, Ed448. Specific exceptions for signature failures, broken trust chains, invalid proofs, and unsigned responses.

EitherOrBoth + Full-Outer-Join Iterators

  • EitherOrBoth — three-variant disjoint union (Left/Right/Both) for values that may be present on either or both of two sides. Inspired by Rust's itertools::EitherOrBoth and Haskell's Data.These. Unlike Either, no side is privileged. Use cases: three-way diffs (insert/delete/update events), layered config merging, multi-source enrichment, dual-validation with independent failure paths, snapshot comparison, request/response pairing. Full surface: map, mapLeft, mapRight, mapAny, swap, proceed, apply, containsLeft, containsRight, plus left()/right()/both() free constructors.
  • Iter\merge_join_by / Iter\merge_join_by_key — full-outer-join stream producers yielding EitherOrBoth events. merge_join_by is a lazy two-cursor merge over sorted inputs (O(1) memory, Comparison\Order-returning comparator). merge_join_by_key is a hash-based variant for keyed inputs that need no pre-sorting (O(|right|) memory).

IO Toolkit Expansion

Eight new handle types for streaming composition:

  • IterableReadHandle — lazily consume an iterable<string> without buffering.
  • ConcatReadHandle — read from two handles in sequence, switching at EOF.
  • JoinedReadWriteHandle — combine separate read and write handles into one.
  • TeeWriteHandle — fan out writes to two handles with backpressure buffering.
  • SinkWriteHandle / SinkReadHandle / SinkReadWriteHandle/dev/null-like handles for discarding writes and reporting EOF immediately on reads.
  • TruncatedReadHandle — silently report EOF after N bytes.
  • BoundedReadHandle — throw RuntimeException if the underlying handle exceeds N bytes.
  • FixedLengthReadHandle — read exactly N bytes, throw on premature EOF.

Plus IO\copy_chunked() and IO\copy_bidirectional_chunked() for explicit chunk-size control.

Type System: Covariance

Read-only template parameters across the library are now annotated @template-covariant, letting values flow into wider declarations:

  • Async\Awaitable<T>, Promise\PromiseInterface<T>
  • Result\ResultInterface<T>, Result\Success<T>, Result\Failure<T, Te>
  • Option\Option<T>
  • Either\Either<TLeft, TRight>, Either\Left<TLeft>, Either\Right<TRight>
  • Tree\NodeInterface<T>, Tree\LeafNode<T>, Tree\TreeNode<T>
  • Immutable Collection interfaces and implementations (Map, Set, Vector)

Async\Sequence, KeyedSequence, Semaphore, and KeyedSemaphore now correctly distinguish contravariant inputs from covariant outputs.

HTTP/2 (H2)

  • New unified Configuration replacing the deprecated ClientConfiguration and ServerConfiguration. Both ClientConnection and ServerConnection accept it. Client-side BDP auto-tuning is now available when maxReceiveWindowSize is set on the unified config.

TCP & Type Additions

  • TCP\bindTo — bind to a specific local address before connecting or listening. Available on both ConnectConfiguration and ListenConfiguration with withBindTo() builders; connect() respects it via socket.bindto.
  • Type\bool() — now coerces 'true'/'false' string literals (thanks @veewee, #735).
  • Type\class_string — allow null argument to assert or coerce a bare class-string.
  • HTTP\Client\SendConfiguration::$connectionTimeout — per-request maximum duration for TCP + TLS handshake, using a linked cancellation token.

Fixes

  • IO\copy() flushes the writer if it implements BufferedWriteHandleInterface — no data left in buffers.
  • Async\State no longer captures $this in queued callbacks, fixing delayed GC of Deferred/Awaitable chains.
  • URI correctly parses bare IPv6 addresses (e.g., http://::1/path) as IPHost instead of misparsing as a registered name with numeric port.
  • H2 separates maxConcurrent (peer's limit on our streams) from peerMaxConcurrent (our limit on peer's streams), so client's own SETTINGS no longer limit its outgoing streams.
  • H2\BDPEstimator emits an initial connection-level WINDOW_UPDATE during initialize(), bringing the receive window from the RFC default (65535) up to initialWindowSize to prevent flow-control stalls under burst concurrency.
  • H2 waiter notification copies the list before iterating and properly removes satisfied waiters — no iteration corruption or memory leaks.
  • IO\ResourceHandle read/write callbacks and cancellation subscriptions null out the suspension reference before resuming or throwing — no more "Must call suspend() before calling throw()" errors during handle destruction or shutdown races.
  • RFC 2047 encoded-word encoder no longer embeds CRLF line folding in the output; folding is now the header serializer's responsibility, fixing header/body separation in serialized messages.

Deprecations

Will be removed in PSL 7.0:

  • TCP\Socket — use ConnectConfiguration::$bindTo / ListenConfiguration::$bindTo.
  • H2\ClientConfiguration and H2\ServerConfiguration — use the unified H2\Configuration.

CI

  • Added httpbun, microsocks, and tinyproxy services to unit-tests, code-coverage, mutation-tests, and package-tests workflows for HTTP client integration testing.

Install: composer require php-standard-library/psl:^6.2

Don't miss a new psl release

NewReleases is sending notifications on new releases.