Problem
compression::StreamingDecoder::new(encoding: &str, ...) matches encoding as a single exact token ("gzip" | "x-gzip", "deflate", "br", "zstd", "" | "identity") and errors on anything else (protocols/turnloop-http/src/compression.rs). A Content-Encoding header is legally a comma-separated list of codings applied in order, and a server can also repeat the header across multiple lines. Neither shape is handled: the whole header value is matched as one string and fails.
Why it matters
Named by an independent review of Perry's P11 lane (the perry CLI's HTTP client, built on turnloop_http). A legal gzip, gzip — or two separate Content-Encoding header lines — failed the whole response with UND_ERR_NOT_SUPPORTED. This is a new failure mode specifically for that lane: it's the first Perry consumer to send its own Accept-Encoding, so the reqwest-based client it replaces never triggered it (it asked for no compression at all, so this path was never exercised on real traffic).
P11 worked around it on the caller side rather than in this crate — a_content_encoding_list_is_split_innermost_last pins the caller-side fix: the header value is split and each coding applied innermost-last, across every header line. compression::StreamingDecoder's own single-token match in new is unchanged.
What would fix it
Accept a list at the API boundary — an iterator of coding tokens, or split-and-chain internally — applying codings innermost-last (the last-listed encoding is the outermost, first to decode), and merging repeated Content-Encoding header lines the same way any repeated header is merged. (This is a different gap from turnloop#54, which is about StreamingDecoder::process's "needs more input" vs. "output full" ambiguity — that's after construction; this is new's single-token match.)
Problem
compression::StreamingDecoder::new(encoding: &str, ...)matchesencodingas a single exact token ("gzip" | "x-gzip","deflate","br","zstd","" | "identity") and errors on anything else (protocols/turnloop-http/src/compression.rs). AContent-Encodingheader is legally a comma-separated list of codings applied in order, and a server can also repeat the header across multiple lines. Neither shape is handled: the whole header value is matched as one string and fails.Why it matters
Named by an independent review of Perry's P11 lane (the
perryCLI's HTTP client, built onturnloop_http). A legalgzip, gzip— or two separateContent-Encodingheader lines — failed the whole response withUND_ERR_NOT_SUPPORTED. This is a new failure mode specifically for that lane: it's the first Perry consumer to send its ownAccept-Encoding, so thereqwest-based client it replaces never triggered it (it asked for no compression at all, so this path was never exercised on real traffic).P11 worked around it on the caller side rather than in this crate —
a_content_encoding_list_is_split_innermost_lastpins the caller-side fix: the header value is split and each coding applied innermost-last, across every header line.compression::StreamingDecoder's own single-token match innewis unchanged.What would fix it
Accept a list at the API boundary — an iterator of coding tokens, or split-and-chain internally — applying codings innermost-last (the last-listed encoding is the outermost, first to decode), and merging repeated
Content-Encodingheader lines the same way any repeated header is merged. (This is a different gap from turnloop#54, which is aboutStreamingDecoder::process's "needs more input" vs. "output full" ambiguity — that's after construction; this isnew's single-token match.)