diff --git a/modules/caddyhttp/encode/zstd/zstd.go b/modules/caddyhttp/encode/zstd/zstd.go index b5a0299d..1706de89 100644 --- a/modules/caddyhttp/encode/zstd/zstd.go +++ b/modules/caddyhttp/encode/zstd/zstd.go @@ -15,6 +15,8 @@ package caddyzstd import ( + "fmt" + "github.com/klauspost/compress/zstd" "github.com/caddyserver/caddy/v2" @@ -27,7 +29,13 @@ func init() { } // Zstd can create Zstandard encoders. -type Zstd struct{} +type Zstd struct { + // The compression level. Accepted values: fastest, better, best, default. + Level string `json:"level,omitempty"` + + // Compression level refer to type constants value from zstd.SpeedFastest to zstd.SpeedBestCompression + level zstd.EncoderLevel +} // CaddyModule returns the Caddy module information. func (Zstd) CaddyModule() caddy.ModuleInfo { @@ -39,6 +47,37 @@ func (Zstd) CaddyModule() caddy.ModuleInfo { // UnmarshalCaddyfile sets up the handler from Caddyfile tokens. func (z *Zstd) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { + d.Next() // consume option name + if !d.NextArg() { + return nil + } + levelStr := d.Val() + if ok, _ := zstd.EncoderLevelFromString(levelStr); !ok { + return d.Errf("unexpected compression level, use one of '%s', '%s', '%s', '%s'", + zstd.SpeedFastest, + zstd.SpeedBetterCompression, + zstd.SpeedBestCompression, + zstd.SpeedDefault, + ) + } + z.Level = levelStr + return nil +} + +// Provision provisions z's configuration. +func (z *Zstd) Provision(ctx caddy.Context) error { + if z.Level == "" { + z.Level = zstd.SpeedDefault.String() + } + var ok bool + if ok, z.level = zstd.EncoderLevelFromString(z.Level); !ok { + return fmt.Errorf("unexpected compression level, use one of '%s', '%s', '%s', '%s'", + zstd.SpeedFastest, + zstd.SpeedDefault, + zstd.SpeedBetterCompression, + zstd.SpeedBestCompression, + ) + } return nil } @@ -51,7 +90,13 @@ func (z Zstd) NewEncoder() encode.Encoder { // The default of 8MB for the window is // too large for many clients, so we limit // it to 128K to lighten their load. - writer, _ := zstd.NewWriter(nil, zstd.WithWindowSize(128<<10), zstd.WithEncoderConcurrency(1), zstd.WithZeroFrames(true)) + writer, _ := zstd.NewWriter( + nil, + zstd.WithWindowSize(128<<10), + zstd.WithEncoderConcurrency(1), + zstd.WithZeroFrames(true), + zstd.WithEncoderLevel(z.level), + ) return writer } @@ -59,4 +104,5 @@ func (z Zstd) NewEncoder() encode.Encoder { var ( _ encode.Encoding = (*Zstd)(nil) _ caddyfile.Unmarshaler = (*Zstd)(nil) + _ caddy.Provisioner = (*Zstd)(nil) )