contentdisposition

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Jul 18, 2026 License: MIT Imports: 3 Imported by: 0

Documentation

Overview

Package contentdisposition creates and parses HTTP Content-Disposition headers. It is a port of the npm content-disposition package using only the Go standard library, and it exposes the two operations that package offers: Format builds a header value from a filename, and Parse decodes a header value back into its type and parameters.

The Content-Disposition header tells a client how a response body should be handled: "inline" to display it in place, or "attachment" to save it, most often under a suggested filename. You use Format on the server side when streaming a download so the browser offers a sensible "Save As" name, and you use Parse on the client side, or in multipart/form-data handling, to recover the disposition type and filename a peer sent.

Format is careful about non-ASCII filenames because a bare filename parameter may only carry ASCII. When the name is pure ASCII it emits a single quoted filename parameter, escaping embedded quotes and backslashes. When the name contains bytes above 0x7f it additionally emits an RFC 5987 filename* parameter: the value is prefixed with "UTF-8”" and every byte outside the RFC 5987 attr-char set is percent-encoded with lower-case hex. By default a legacy filename parameter is emitted alongside it as an ASCII fallback, built by replacing each non-ASCII byte with '?'; WithFallback(false) suppresses that fallback, and WithType selects the disposition type (default "attachment").

Parse splits the header on unquoted semicolons, lower-cases the disposition type and each parameter name, and unescapes quoted-string values. A parameter whose name ends in "*" is treated as an RFC 5987 ext-value and decoded from its charset'lang'percent-encoded form; only the "utf-8" and "iso-8859-1" charsets are accepted and any other charset, or a malformed percent escape, produces an error. When both a filename and a filename* parameter are present the decoded extended value wins and is stored under the "filename" key, matching the precedence browsers apply. An empty or whitespace-only header is an error, while a header with only a type (for example "inline") parses to that type with an empty filename.

Parity with the Node original is close for the common download and upload cases: the Format output for ASCII and UTF-8 filenames matches content-disposition, and Parse recovers the same type, filename, and parameter map. The differences are deliberate simplifications. This port does not perform the library's full ISO-8859-1 to UTF-8 transcoding of legacy values, it does not reproduce every validation error message verbatim, and it decodes rather than aggressively rejecting unusual-but-parseable inputs, so it favors round-trip fidelity over byte-for-byte error parity.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Format

func Format(filename string, opts ...Option) string

Format builds a Content-Disposition header value for the given filename. By default the type is "attachment". When the filename contains non-ASCII characters, both a plain ASCII fallback filename and an RFC 5987 filename* parameter are emitted.

Example

ExampleFormat builds a Content-Disposition header for a download with an ASCII filename. The default disposition type is "attachment", which tells a browser to save the body rather than display it. A pure-ASCII name is emitted as a single quoted filename parameter. This is what a server sends so the browser offers a sensible "Save As" name.

package main

import (
	"fmt"

	"github.com/malcolmston/express/contentdisposition"
)

func main() {
	fmt.Println(contentdisposition.Format("report.pdf"))
}
Output:
attachment; filename="report.pdf"
Example (Unicode)

ExampleFormat_unicode shows how a non-ASCII filename is encoded. Because a bare filename parameter may only carry ASCII, an RFC 5987 filename* parameter is added with the name UTF-8 percent-encoded. By default a legacy ASCII fallback is emitted alongside it, built by replacing each non-ASCII byte with '?'. Browsers that understand filename* use the decoded Unicode name and ignore the fallback.

package main

import (
	"fmt"

	"github.com/malcolmston/express/contentdisposition"
)

func main() {
	fmt.Println(contentdisposition.Format("naïve.txt"))
}
Output:
attachment; filename="na??ve.txt"; filename*=UTF-8''na%c3%afve.txt

Types

type ContentDisposition

type ContentDisposition struct {
	// Type is the disposition type, e.g. "attachment" or "inline".
	Type string
	// Filename is the decoded filename, if any (from filename* or filename).
	Filename string
	// Parameters holds all disposition parameters (including "filename").
	Parameters map[string]string
}

ContentDisposition represents a parsed Content-Disposition header.

func Parse

func Parse(s string) (ContentDisposition, error)

Parse parses a Content-Disposition header value. If no disposition type is present the default "attachment" is used. A filename* parameter takes precedence over a plain filename parameter.

Example

ExampleParse decodes a Content-Disposition header value back into its type and filename. The disposition type is lower-cased and quoted parameter values are unescaped. When both filename and filename* are present the decoded extended value wins, matching browser precedence. Here a simple attachment header is parsed into its type and suggested filename.

package main

import (
	"fmt"

	"github.com/malcolmston/express/contentdisposition"
)

func main() {
	cd, err := contentdisposition.Parse(`attachment; filename="report.pdf"`)
	if err != nil {
		fmt.Println("error:", err)
		return
	}
	fmt.Println(cd.Type, cd.Filename)
}
Output:
attachment report.pdf

type Option

type Option func(*options)

Option configures how a Content-Disposition header is formatted.

func WithFallback

func WithFallback(fallback bool) Option

WithFallback controls whether an ASCII fallback filename parameter is emitted when the filename contains non-ASCII characters. It is true by default; setting it to false suppresses the plain filename parameter.

func WithType

func WithType(t string) Option

WithType sets the disposition type (default "attachment").

Jump to

Keyboard shortcuts

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