zstd

package
v1.1.10 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 7, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

README

compress/zstd

compress/zstd is an encoder-only RFC 8878 package for TinyGo and Go web servers. It streams a valid Content-Encoding: zstd representation and calculates its SHA-256 digest during output, so cache entries can retain the encoded bytes and a strong ETag without hashing the bytes in a second pass.

encoded, result, err := zstd.EncodeAll(body)
if err != nil {
	return err
}
header.Set("Content-Encoding", zstd.ContentEncoding)
header.Set("ETag", result.ETag())

ETag calculation is enabled by default. Disable it for responses such as Cache-Control: no-store; this avoids allocating and updating SHA-256:

encoded, result, err := zstd.EncodeAll(body, zstd.WithETag(false))
// result.ETagEnabled is false, result.ETag() is empty, and SHA256 is zero.

NewWriter provides the bounded streaming form. Call Close, then Result; closing the encoder does not close its destination.

Flush emits the buffered input as complete blocks so a reader can decode everything written so far, which is what streaming responses and server-sent events need between chunks. It neither ends the frame nor flushes the destination, so flush the destination separately:

if _, err := z.Write(chunk); err != nil {
	return err
}
if err := z.Flush(); err != nil {
	return err
}
w.(http.Flusher).Flush()

Flushing before a block fills reduces the compression ratio, so flush per chunk rather than per Write.

Implementation selection

  • normal host Go builds use github.com/klauspost/compress/zstd
  • TinyGo builds use this package's bounded pure-Go encoder
  • go build -tags force_tinygo_logic forces the TinyGo-compatible encoder on host Go

Both implementations expose the same Writer, Result, Option, and EncodeAll API. Encoded bytes and therefore ETags may differ between implementations.

The host backend uses the klauspost default compression level with one encoder, a 128 KiB window, lower-memory mode, and no frame checksum. The TinyGo backend has the following supported subset:

  • standard Zstandard frames with a 128 KiB window
  • raw and RLE blocks of at most 128 KiB, including profitable interior runs
  • a low-memory compressed level using one LZ match and RLE sequence tables
  • streaming output with at most one input block retained
  • Flush at block boundaries without ending the frame
  • SHA-256 and encoded size calculated over bytes successfully written
  • strong, quoted ETag formatting for the encoded representation

Public API exclusions

  • decoding
  • dictionaries and the seekable format
  • compression-level or dictionary options
  • frame content checksums (the cache digest is separate)

The TinyGo backend additionally omits Huffman literals, general FSE tables, multi-match blocks, unsafe code, assembly, and CGo.

Content without a useful match can become slightly larger. This basic level is optimized for small implementation size and bounded TinyGo memory rather than compression-ratio parity with general-purpose Zstandard encoders.

Documentation

Overview

Package zstd writes RFC 8878 Zstandard frames and calculates cache metadata over the encoded representation while it is emitted.

Host Go uses github.com/klauspost/compress/zstd. TinyGo uses this package's bounded encoder, which can also be selected on host Go with the shared force_tinygo_logic build tag. Both implementations expose the same API and calculate Result's SHA-256 digest over bytes successfully written.

Index

Examples

Constants

View Source
const ContentEncoding = "zstd"

ContentEncoding is the HTTP content-coding token for Zstandard.

Variables

View Source
var (
	ErrClosed            = errors.New("zstd: writer is closed")
	ErrResultUnavailable = errors.New("zstd: result is unavailable before a successful close")
)

Functions

This section is empty.

Types

type Option

type Option interface {
	// contains filtered or unexported methods
}

Option configures both the host-Go and TinyGo encoders.

func WithETag

func WithETag(enabled bool) Option

WithETag controls whether SHA-256 cache metadata is calculated while the encoded representation is written. It is enabled by default. When disabled, Result.SHA256 is zero and Result.ETag returns an empty string.

type Result

type Result struct {
	Size        int64
	SHA256      [sha256.Size]byte
	ETagEnabled bool
}

Result describes an encoded representation. SHA256 covers exactly Size bytes written to the destination, including the Zstandard frame headers.

func EncodeAll

func EncodeAll(src []byte, options ...Option) ([]byte, Result, error)

EncodeAll encodes src, returning the frame and its cache metadata. The digest is produced while the frame is written; the encoded bytes are not traversed a second time.

Example
package main

import (
	"fmt"

	"github.com/shibukawa/tinygodriver/compress/zstd"
)

func main() {
	encoded, result, err := zstd.EncodeAll([]byte("response body"))
	if err != nil {
		panic(err)
	}
	fmt.Println(len(encoded) == int(result.Size))
	fmt.Println(zstd.ContentEncoding)
}
Output:
true
zstd

func (Result) ETag

func (r Result) ETag() string

ETag returns a quoted strong HTTP entity-tag for the encoded representation. It returns an empty string when the encoder used WithETag(false).

type Writer

type Writer struct {
	// contains filtered or unexported fields
}

Writer emits one Zstandard frame through github.com/klauspost/compress/zstd. Writer is not safe for concurrent use. Close must succeed before Result can be read.

func NewWriter

func NewWriter(w io.Writer, options ...Option) (*Writer, error)

NewWriter starts a host-Go Zstandard stream. TinyGo and builds using the force_tinygo_logic tag select the bounded TinyGo encoder instead.

func (*Writer) Close

func (z *Writer) Close() error

Close finishes the frame. It does not close the destination.

func (*Writer) Flush added in v1.0.4

func (z *Writer) Flush() error

Flush emits the buffered input as complete blocks so that everything written so far can be decoded, and returns once those bytes reach the destination. It does not end the frame and it does not flush the destination itself. Flushing before a block fills reduces the compression ratio.

func (*Writer) Result

func (z *Writer) Result() (Result, error)

Result returns the encoded size and SHA-256 digest after a successful Close.

func (*Writer) Write

func (z *Writer) Write(p []byte) (int, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL