This commit is contained in:
Javier Casares 2026-08-18 07:00:18 +00:00
commit 77d0cea926
995 changed files with 28142 additions and 8603 deletions

View file

@ -5,6 +5,172 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 3.0.0 - 2026-07-20
### Added
- Add `DiagnosticValue::escape()` to escape controls and malformed UTF-8 in diagnostics
- Add `GuzzleHttp\Psr7\Exception\TimeoutException` for timed-out stream operations
- Add `GuzzleHttp\Psr7\Utils::redactUserInfoInString()` to redact the userinfo of a raw URI string within text
- Promote `GuzzleHttp\Psr7\Rfc3986` to public API with `isValid*()` predicates and `canonicalizeIpv6()`
- Add `GuzzleHttp\Psr7\UriNormalizer::CANONICALIZE_IPV6_HOST` to `PRESERVING_NORMALIZATIONS`
### Changed
- Require `psr/http-message:^2.0` and add native parameter and return types
- Require `psr/http-factory:^1.1`
- Reject native PHP serialization of stream implementations
- Preserve request method casing, except `ServerRequest::fromGlobals()` still uppercases
- Reject empty arrays and non-string values as header values
- Reject invalid uploaded file trees and invalid parsed body values
- Reject uploaded file specs missing `tmp_name`, `size`, or `error`
- Reject non-integer and negative uploaded file `error` values
- Reject invalid stream/upload sizes, buffer high-water marks, and dropping-stream limits
- Rewind seekable uploaded-file streams before copying in `UploadedFile::moveTo()`
- Reject negative `read()` lengths across all stream implementations
- Detect the `+` flag anywhere in a mode for `Stream::isReadable()`/`isWritable()`
- Reject empty strings returned by `PumpStream` source callables
- Discard buffered bytes on `PumpStream` close and detach
- Restore the original stream position after `Message::bodySummary()`
- Allow `null` for the `Message::bodySummary()` truncation length to use the default
- Validate `LimitStream` offset/limit and track non-seekable offset by bytes skipped
- Make `FnStream` close and detach terminal, calling close callbacks at most once
- Suppress exceptions from `FnStream` close callbacks during destructor cleanup
- Make `CachingStream::close()` idempotent, preserving remote cleanup after detach
- Do not move the `CachingStream` cursor when a `SEEK_END` target on an unknown-size stream is rejected
- Normalize multiple leading slashes in `Uri::getPath()` and origin-form request targets
- Serialize authority-less `file` URIs with rootless paths without the `//` separator
- Serialize authority-less `file` URIs with empty paths as `file:` instead of the unparseable `file://`
- Remove dot segments above the root per RFC 3986, prefixing authority-less `//` paths with `/.`
- Return a network-path reference from `UriResolver::relativize()` when an empty-path target requires one
- Stop returning an empty reference from `UriResolver::relativize()` when it would inherit the base fragment
- Stop throwing from `UriResolver::relativize()` when an equal-path target's last path segment contains a colon
- Harden URI host validation (delimiters, backslashes, IPv6, embedded ports); require schemes to start with a letter
- Validate `Uri::fromParts()` ports instead of casting them
- Treat ports 80 and 443 as defaults for the `ws` and `wss` schemes
- Use the `ws` and `wss` default ports in `UriComparator::isCrossOrigin()` port comparisons
- Redact all non-empty URI userinfo in `Utils::redactUserInfo()`
- Rebuild server request URIs from `$_SERVER` by `REQUEST_METHOD`, using target authority before `SERVER_PORT`
- Remove userinfo from absolute-form `REQUEST_URI` targets in `ServerRequest::fromGlobals()`
- Reject zero-port `HTTP_HOST` and malformed `SERVER_PORT` in `ServerRequest::getUriFromGlobals()`
- Reject malformed `REQUEST_METHOD` and `SERVER_PROTOCOL` server values in `ServerRequest::fromGlobals()`
- Reject zero-port `Host` and normalize leading-zero ports in `Message::parseRequest()`
- Reject duplicate `Host` headers and validate present values for all request-target forms
- Reject zero-port, hostless, and userinfo absolute-form request targets in `Message::parseRequest()`
- Synchronize the `Host` header in `Request::withUri()` when the URI changes or Host is empty
- Include the URI port in `Host` headers synthesized by `Message::toString()`
- Validate the Host header synthesized by `Message::toString()` from the request URI
- Include non-default URI ports in `Host` headers set by `Utils::modifyRequest()` URI changes
- Accept `OPTIONS *` and `CONNECT` authority-form request targets in `Message::parseRequest()`
- Hide credential-bearing URI, server, and cookie arguments in stack traces on PHP 8.2+
- Reject malformed HTTP request/response start-lines
- Unfold obsolete HTTP/1.0 line folding for all valid request method tokens
- Reject empty and control-character request targets in `Request::withRequestTarget()`
- Validate iterator chunks passed to `Utils::streamFor()`
- Validate unsupported values passed to `Query::build()`
- Reject non-finite float values in `Query::build()` and `MultipartStream` contents
- Reject non-finite float values in iterator chunks passed to `Utils::streamFor()`
- `Utils::streamFor()` now rejects non-string scalar bodies
- `Uri::withQueryValues()` now rejects non-string values
- Reject invalid `Utils::modifyRequest()` change values
- Use PHP debug type names in type error messages
- Changed `Utils::copyToStream()` to throw when destination streams cannot make progress
- Throw `TimeoutException` from `Stream` read/write and `Utils` copy/hash/readLine on stream timeouts
- Throw `TimeoutException` from `AppendStream::read()`, `CachingStream::read()`, and `Utils::tryGetContents()` on stream timeouts
- Re-throw `TimeoutException` from `InflateStream` when the decoded source stream times out
- Close the compressed source stream from `InflateStream::close()`
- Return the number of bytes copied from `Utils::copyToStream()`
- Throw `OverflowException` when stream byte counts or offsets exceed `PHP_INT_MAX`
- Translate `StreamWrapper` runtime failures to PHP stream failure values
- Stop adding default `Content-Length` to `multipart/form-data` parts (RFC 7578 §4.8)
- Escape multipart `Content-Disposition` parameters and reject unsafe boundaries and part headers
- Preserve trailing whitespace in custom `MultipartStream` part header values
- Preserve explicit custom `MultipartStream` boundary `'0'` instead of replacing it with a generated boundary
- Made static utility classes non-instantiable
- Validate bracketed IP-literal hosts consistently between parsing and `withHost()`, including userinfo forms
- Percent-encode raw control bytes in userinfo before bracketed IP-literal hosts instead of parsing mutated values
- Reject invalid UTF-8 and preserve percent-sequences in userinfo before bracketed IP-literal hosts
- Normalize percent-encoded octets in the URI host to uppercase hex
- Canonicalize IPv6 hosts to RFC 5952 form in `Uri` construction, `fromParts()`, and `withHost()`
- Canonicalize bracketed IPv6 hosts in `UriComparator::isCrossOrigin()`
- Reject malformed percent-sequences and percent-encoded bytes forbidden by the URI host policy
- Extend `CAPITALIZE_PERCENT_ENCODING` and `DECODE_UNRESERVED_CHARACTERS` to userinfo and host
- Trim header list elements with only spaces, horizontal tabs, and line terminators in `Header::splitList()`
- Report header parameter PCRE failures explicitly in `Header::parse()`
- Escape controls and malformed UTF-8 consistently in generated exception messages
### Removed
- Dropped support for PHP 7.2 and 7.3
- Removed the `ralouphie/getallheaders` dependency
- Removed deprecated `Header::normalize()` method
## 2.13.0 - 2026-07-16
### Added
- Add `Utils::` `asciiToLower`, `asciiToUpper`, `asciiUcFirst`, `caselessEquals`, `caselessContains`
### Changed
- Use locale-independent ASCII case folding everywhere case is normalized
- Trigger a runtime deprecation for previously deprecated functionality in 2.3.0
## 2.12.5 - 2026-07-13
### Fixed
- Compare header names and hosts with locale-independent ASCII lowercasing
- Compare hosts without locale sensitivity when detecting cross-origin redirects
## 2.12.4 - 2026-07-08
### Changed
- Pass explicit trim characters ahead of the PHP 8.6 trim default change
### Fixed
- Anchor server port and response start-line patterns to the true end of input
- Treat host-less origin-form request targets starting with `//` as paths in `Message::parseRequest()`
- Reject raw DEL bytes in bracketed IP-literal hosts instead of parsing a mutated host
- Reject invalid bytes after a bracketed IP-literal host instead of reparsing a different host
## 2.12.3 - 2026-06-23
### Security
- Validate the URI host so `getHost()` matches the URI authority (GHSA-c2w2-prh8-qm98)
## 2.12.2 - 2026-06-23
### Fixed
- Report URI parsing, filtering, and normalization PCRE failures explicitly
- Report HTTP message parser PCRE failures explicitly
- Fail closed when PCRE validation fails for request targets and hosts
## 2.12.1 - 2026-06-18
### Security
- Reject CR/LF in HTTP method, protocol version, and reason phrase (GHSA-vm85-hxw5-5432)
## 2.12.0 - 2026-06-16
### Deprecated
- Deprecated non-finite float values in `Query::build()` that guzzlehttp/psr7 3.0 rejects
- Deprecated non-finite float multipart contents that guzzlehttp/psr7 3.0 rejects
- Deprecated non-string scalar bodies in `Utils::streamFor()`; cast them to a string for 3.0
- Deprecated non-string `Uri::withQueryValues()` values; cast them to a string for 3.0
## 2.11.1 - 2026-06-12
### Fixed
- Fixed non-finite float values emitting coercion warnings on PHP 8.5
## 2.11.0 - 2026-06-02
### Changed