Skip to content

About

HTTP Content-Encoding header multiplexer (identity, gzip, deflate) — Sendable, Foundation-free.

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

swift-content-encoding

HTTP Content-Encoding multiplexer — decoder (v0.1+) + one-shot encoder (v0.2+) + streaming encoder (v0.5 single-coding, v0.6 multi-coding). Sendable, Foundation-free.

Part of the bare-swift ecosystem.

Install

Add to your Package.swift:

.package(url: "https://github.com/bare-swift/swift-content-encoding.git", from: "0.6.0")

Then depend on the ContentEncoding product:

.product(name: "ContentEncoding", package: "swift-content-encoding")

Usage

Decode (v0.1+)

import ContentEncoding
import Bytes

let body: Bytes = ...                 // raw HTTP response body
let header = "gzip"                   // from response Content-Encoding
let plain = try ContentEncoding.decode(body, contentEncoding: header)

Encode (v0.2+)

import ContentEncoding
import Bytes

let payload: Bytes = ...
let body = try ContentEncoding.encode(payload, contentEncoding: "gzip", level: .default)
// Round-trip: ContentEncoding.decode(body, contentEncoding: "gzip") == payload

Multi-coding works in both directions (encode applies left-to-right; decode reverses):

let body = try ContentEncoding.encode(payload, contentEncoding: "gzip, deflate")
let back = try ContentEncoding.decode(body, contentEncoding: "gzip, deflate")

Streaming encode (v0.5+ single-coding, v0.6+ multi-coding)

import ContentEncoding
import Bytes

var encoder = try ContentEncoding.Streaming.Encoder(contentEncoding: "gzip", level: .default)
encoder.update(chunk1)
encoder.update(chunk2)
let body = try encoder.finish()
let plain = try ContentEncoding.decode(body, contentEncoding: "gzip")
// plain == chunk1 + chunk2

The streaming encoder dispatches to the canonical streaming encoders in swift-gzip / swift-zlib / swift-brotli per the configured coding. Empty / whitespace header and identity coding buffer and return at finish().

Multi-coding headers (v0.6+) stream correctly via cascaded drain() calls on the underlying v0.4+ codec streaming encoders:

var encoder = try ContentEncoding.Streaming.Encoder(
    contentEncoding: "gzip, br", level: .default
)
encoder.update(chunk1)
encoder.update(chunk2)
let compressed = try encoder.finish()
let plain = try ContentEncoding.decode(compressed, contentEncoding: "gzip, br")

Per RFC 9110 § 8.4, codings apply left-to-right at encode time — so "gzip, br" means input → gzip-encode → br-encode → output; the decoder reverses to br-decode → gzip-decode.

(v0.5 threw ContentEncodingError.multipleCodingsNotStreamable for multi-coding; v0.6 supports it. The error case is kept in the enum for backwards-compat but is no longer thrown.)

Supported codings (case-insensitive)

  • identity — passthrough.
  • gzip / x-gzip — RFC 1952 via swift-gzip.
  • deflate / x-deflate — zlib-framed DEFLATE per RFC 7230 § 4.2.2 via swift-zlib. Not raw DEFLATE.
  • br — Brotli (RFC 7932) decode-only via swift-brotli. Encoding br throws .unsupportedEncoding("br") (the encoder ships with swift-brotli v0.2).

Unsupported codings (zstd, compress) throw ContentEncodingError.unsupportedEncoding.

Public API

  • ContentEncoding.decode(_:contentEncoding:) throws(ContentEncodingError) -> Bytes
  • ContentEncoding.encode(_:contentEncoding:level:) throws(ContentEncodingError) -> Bytes
  • ContentEncoding.Level — typealias for Deflate.Encoder.Level (.none / .fast / .default / .best).
  • ContentEncodingError typed-throws enum (2 cases).

Dependencies

  • swift-deflate 0.2.0 — for the Level typealias.
  • swift-gzip 0.2.0 — gzip codec.
  • swift-zlib 0.2.0 — zlib codec.
  • swift-brotli 0.1.0 — Brotli decoder (v0.3+).
  • swift-bytes 0.1.0 — buffer.

Out of scope for v0.3

  • Brotli encoding. Lands when swift-brotli v0.2 ships.
  • zstd, compress.
  • Streaming encoding.
  • Accept-Encoding negotiation.

Documentation

Full DocC documentation: https://bare-swift.github.io/swift-content-encoding/

License

Apache 2.0 with LLVM exception. See LICENSE and NOTICE.

About

HTTP Content-Encoding header multiplexer (identity, gzip, deflate) — Sendable, Foundation-free.

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages