API Index — Namespaces, Packages, Reports, Indices
CompressionMiddleware
in package
implements
MiddlewareInterface
Compression Middleware (gzip / deflate)
Compresses response bodies when the client advertises support via
Accept-Encoding. Skips streaming responses (SSE, Generator, stream()),
responses smaller than the threshold, and optionally requests that already
came through a reverse proxy such as Traefik.
RFC 7231 §5.3.4 compliance:
Accept-Encodingq=0is treated as explicit refusal; compression is skipped.
RFC 7232 §2.1 compliance:
- Strong
ETags on responses that are then compressed are weakened (W/prefix), because the compressed body is not byte-identical to the original.
nginx / mod_deflate parity:
Vary: Accept-Encodingis merged with any existingVaryvalues so that a priorVary: OriginfromCorsMiddlewareis preserved (apr_table_mergen/ngx_http_header_filterparity).Accept-Rangesis cleared on compressed responses becauseRangerequests cannot be satisfied on a compressed body (ngx_http_clear_accept_rangesparity).
Reference usage when OpenSwoole http_compression is disabled:
$app->addMiddleware(new \ZealPHP\Middleware\CompressionMiddleware());
Table of Contents
Interfaces
- MiddlewareInterface
Constants
- PROXY_HEADERS : mixed = ['Forwarded', 'Via', 'X-Forwarded-For', 'X-Forw...
Properties
- $level : int
- $minLength : int
- $skipProxiedRequests : bool
Methods
- __construct() : mixed
- process() : ResponseInterface
- applyCompressionHeaders() : ResponseInterface
- Apply the standard post-compression response headers:
-
Content-Encoding-Content-Length(actual compressed byte count) -Vary: mergeAccept-Encodinginto any existing values (dedup, case-insensitive) -ETag: weaken any strongETag(RFC 7232 §2.1) -Accept-Ranges: clear (compressed body cannot serve byte-range requests) - isAcceptedEncoding() : bool
- Check whether a given encoding token is accepted by the client, honouring
RFC 7231 §5.3.4 q-value semantics:
q=0(orq=0.000…) means explicit refusal. - isProxiedRequest() : bool
- isUncompressible() : bool
- mergeVary() : ResponseInterface
- Merge
$directiveinto the response'sVaryheader, deduplicating case-insensitively. UseswithHeader()on the merged result so the full canonical list is a single header line (RFC 7230 §3.2.2). - weakenEtag() : ResponseInterface
- If the response carries a strong
ETag, weaken it by prependingW/.
Constants
PROXY_HEADERS
private
mixed
PROXY_HEADERS
= ['Forwarded', 'Via', 'X-Forwarded-For', 'X-Forwarded-Host', 'X-Forwarded-Port', 'X-Forwarded-Proto', 'X-Forwarded-Prefix', 'X-Forwarded-Server', 'X-Real-IP']
Properties
$level
private
int
$level
= 6
$minLength
private
int
$minLength
= 1024
$skipProxiedRequests
private
bool
$skipProxiedRequests
= false
Methods
__construct()
public
__construct([int $minLength = 1024 ][, int $level = 6 ][, bool $skipProxiedRequests = false ]) : mixed
Parameters
- $minLength : int = 1024
- $level : int = 6
- $skipProxiedRequests : bool = false
process()
public
process(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface
Parameters
- $request : ServerRequestInterface
- $handler : RequestHandlerInterface
Return values
ResponseInterfaceapplyCompressionHeaders()
Apply the standard post-compression response headers:
- Content-Encoding
- Content-Length (actual compressed byte count)
- Vary: merge Accept-Encoding into any existing values (dedup, case-insensitive)
- ETag: weaken any strong ETag (RFC 7232 §2.1)
- Accept-Ranges: clear (compressed body cannot serve byte-range requests)
private
applyCompressionHeaders(ResponseInterface $response, string $encoding, string $compressed) : ResponseInterface
Parameters
- $response : ResponseInterface
- $encoding : string
- $compressed : string
Return values
ResponseInterfaceisAcceptedEncoding()
Check whether a given encoding token is accepted by the client, honouring
RFC 7231 §5.3.4 q-value semantics: q=0 (or q=0.000…) means explicit refusal.
private
isAcceptedEncoding(string $accept, string $encoding) : bool
Parses the comma-separated Accept-Encoding field value looking for the
token (case-insensitive, already lowercased by the caller). If the token
is found and its q-value is absent or > 0, it is accepted. A q-value of
exactly zero (any number of trailing zeros, e.g. "0", "0.0", "0.000")
means the encoding is explicitly refused.
Parameters
- $accept : string
- $encoding : string
Return values
boolisProxiedRequest()
private
isProxiedRequest(ServerRequestInterface $request) : bool
Parameters
- $request : ServerRequestInterface
Return values
boolisUncompressible()
private
isUncompressible(string $ct) : bool
Parameters
- $ct : string
Return values
boolmergeVary()
Merge $directive into the response's Vary header, deduplicating
case-insensitively. Uses withHeader() on the merged result so the
full canonical list is a single header line (RFC 7230 §3.2.2).
private
mergeVary(ResponseInterface $response, string $directive) : ResponseInterface
Apache parity: apr_table_mergen(r->headers_out, "Vary", "Accept-Encoding")
nginx parity: ngx_http_header_filter Vary conditional add
Parameters
- $response : ResponseInterface
- $directive : string
Return values
ResponseInterfaceweakenEtag()
If the response carries a strong ETag, weaken it by prepending W/.
private
weakenEtag(ResponseInterface $response) : ResponseInterface
A compressed body is a transformed representation — it is NOT byte-identical to the original, so the strong validator must not survive.
nginx parity: ngx_http_weak_etag() (ngx_http_core_module.c:1753)
RFC reference: RFC 7232 §2.1
Parameters
- $response : ResponseInterface