Documentation
¶
Overview ¶
Package contenttype parses and formats HTTP Content-Type header values, modeled on the npm "content-type" package and RFC 7231, using only the Go standard library. It provides Parse to decode a header value into a ContentType struct and Format to serialize a ContentType back into a header value.
The Content-Type header names the media type of a message body and carries optional parameters such as the character set. You use Parse on the receiving side to learn the media type and, for example, the charset of a request or response body, and Format on the sending side to build a well-formed header from a media type and a parameter map. Both operations are pure functions, so they are convenient to test and to reuse outside of a live HTTP handler.
Parse splits the value at the first ';' into a media type and a parameter list. The media type is trimmed and lower-cased and must match the RFC 7230 token "/" token grammar or an error is returned. The remainder is scanned one "; name=value" parameter at a time with a regular expression built from the token character class; each parameter name is lower-cased, and a value given as a quoted string is unquoted and has its backslash escapes removed. A value that is a bare token is taken verbatim. Any input that does not match the parameter grammar, including a trailing "name" with no "=value", produces an error.
Format is the inverse and validates as it goes. The Type field must be a valid media type or Format returns an error. Parameters are emitted in sorted name order so the output is deterministic, which makes it stable to compare or snapshot; each name must be a valid token. A parameter value that is itself a valid token is written unquoted, while any other value is wrapped in double quotes with backslashes and quotes escaped. Note that parameter names are lower-cased on Parse but Format writes the names it is given as-is, and that parameter values preserve their original case in both directions.
The result is faithful to the npm content-type package for typical headers: the token and quoted-string grammar, the lower-casing of the type and parameter names, the case preservation of values, and the quoting rules on output all match. The main intentional differences are that this port sorts parameters by name for deterministic output rather than preserving insertion order, and it uses Go-idiomatic error values instead of thrown TypeError objects, so error messages are prefixed with "contenttype:" rather than matching the Node text verbatim.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Format ¶
func Format(ct ContentType) (string, error)
Format serializes a ContentType back into a header value such as "text/html; charset=utf-8". Parameter values that are not valid tokens are quoted and escaped. Parameters are emitted in sorted name order. It returns an error if the type or any parameter name is invalid.
Example ¶
ExampleFormat serializes a ContentType back into a header value, the inverse of Parse. Parameters are emitted in sorted name order so the output is deterministic and stable to compare or snapshot. A parameter value that is a valid token is written unquoted; anything else is quoted and escaped. Here a JSON media type with a charset parameter is rendered into a header string.
package main
import (
"fmt"
"github.com/malcolmston/express/contenttype"
)
func main() {
s, err := contenttype.Format(contenttype.ContentType{
Type: "application/json",
Parameters: map[string]string{"charset": "utf-8"},
})
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Println(s)
}
Output: application/json; charset=utf-8
Types ¶
type ContentType ¶
type ContentType struct {
// Type is the media type, e.g. "text/html". It is always lower-cased.
Type string
// Parameters holds the media type parameters keyed by their lower-cased
// names, e.g. {"charset": "utf-8"}.
Parameters map[string]string
}
ContentType represents a parsed media type and its parameters.
func Parse ¶
func Parse(s string) (ContentType, error)
Parse parses a Content-Type header value such as "text/html; charset=utf-8". The media type and parameter names are lower-cased; quoted parameter values are unquoted and unescaped. It returns an error if the value is malformed.
Example ¶
ExampleParse decodes a Content-Type header value into its media type and parameters. The value is split at the first ';' into the media type and a parameter list. The media type and parameter names are lower-cased, while parameter values keep their original case, and quoted values are unquoted. Here a typical header yields the media type and its charset parameter.
package main
import (
"fmt"
"github.com/malcolmston/express/contenttype"
)
func main() {
ct, err := contenttype.Parse("text/html; charset=utf-8")
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Println(ct.Type, ct.Parameters["charset"])
}
Output: text/html utf-8