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/Responsevalue objects with streaming bodies (ReadHandleInterface),FieldMap(ordered, case-insensitive headers with lazy index),ProtocolVersioncovering HTTP/1.0 through HTTP/3, trailers asAsync\Awaitable<FieldMap>, status/method constants per RFC 9110, andTransaction/Exchangefor 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,RedirectClientandRetryClientdecorators, per-requestSendConfiguration, SSRF protection viaDeniedDestinationsMiddleware, 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 fluentwith*()mutation, address methods acceptingstring|Mailbox|AddressList, streamingserialize()/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-levelConnectionfor protocol-level operations and high-levelTransportmanaging 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.SystemResolvermirrors 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).RacingResolverraces multiple nameservers concurrently,SplitHorizonResolverroutes by domain,SearchDomainResolverexpands short names,HostsFileResolverchecks the OS hosts file,CachedResolverdecorator with TTL-aware caching, andStaticResolverfor 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.SecureResolvervalidates RRSIG signatures,TrustChainResolverwalks DS/DNSKEY from root to target zone,CachedTrustChainResolverfor performance,StaticTrustChainResolverfor 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'sitertools::EitherOrBothand Haskell'sData.These. UnlikeEither, 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, plusleft()/right()/both()free constructors.Iter\merge_join_by/Iter\merge_join_by_key— full-outer-join stream producers yieldingEitherOrBothevents.merge_join_byis a lazy two-cursor merge over sorted inputs (O(1) memory,Comparison\Order-returning comparator).merge_join_by_keyis 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 aniterable<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— throwRuntimeExceptionif 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
Collectioninterfaces and implementations (Map,Set,Vector)
Async\Sequence, KeyedSequence, Semaphore, and KeyedSemaphore now correctly distinguish contravariant inputs from covariant outputs.
HTTP/2 (H2)
- New unified
Configurationreplacing the deprecatedClientConfigurationandServerConfiguration. BothClientConnectionandServerConnectionaccept it. Client-side BDP auto-tuning is now available whenmaxReceiveWindowSizeis set on the unified config.
TCP & Type Additions
TCP\bindTo— bind to a specific local address before connecting or listening. Available on bothConnectConfigurationandListenConfigurationwithwithBindTo()builders;connect()respects it viasocket.bindto.Type\bool()— now coerces'true'/'false'string literals (thanks @veewee, #735).Type\class_string— allownullargument to assert or coerce a bareclass-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 implementsBufferedWriteHandleInterface— no data left in buffers.Async\Stateno longer captures$thisin queued callbacks, fixing delayed GC ofDeferred/Awaitablechains.URIcorrectly parses bare IPv6 addresses (e.g.,http://::1/path) asIPHostinstead of misparsing as a registered name with numeric port.H2separatesmaxConcurrent(peer's limit on our streams) frompeerMaxConcurrent(our limit on peer's streams), so client's own SETTINGS no longer limit its outgoing streams.H2\BDPEstimatoremits an initial connection-levelWINDOW_UPDATEduringinitialize(), bringing the receive window from the RFC default (65535) up toinitialWindowSizeto prevent flow-control stalls under burst concurrency.H2waiter notification copies the list before iterating and properly removes satisfied waiters — no iteration corruption or memory leaks.IO\ResourceHandleread/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— useConnectConfiguration::$bindTo/ListenConfiguration::$bindTo.H2\ClientConfigurationandH2\ServerConfiguration— use the unifiedH2\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