httpheader

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 19, 2019 License: MIT Imports: 8 Imported by: 4

README

httpheader

GoDoc Travis build status Codecov Go Report Card

This is a Go package to parse and generate standard HTTP headers correctly. It knows about complex headers like Accept, Prefer, Link. Unlike many other implementations, it handles all the tricky bits of syntax like quoted commas, multiple header lines, Unicode parameters. It gives you convenient structures to work with, and can serialize them back into HTTP.

This package is distributed under the MIT license, and hosted on GitHub. If it doesn't yet support a header that you need, feel free to open an issue there.

Installation

go get github.com/vfaronov/httpheader

Example

const request = `GET / HTTP/1.1
Host: api.example.com
User-Agent: MyApp/1.2.3 python-requests/2.22.0
Accept: text/*, application/json;q=0.8
Forwarded: for="198.51.100.30:14852";by="[2001:db8::ae:56]";proto=https

`

r, _ := http.ReadRequest(bufio.NewReader(strings.NewReader(request)))

forwarded := httpheader.Forwarded(r.Header)
fmt.Println("received request from user at", forwarded[0].For.IP)

for _, product := range httpheader.UserAgent(r.Header) {
	if product.Name == "MyApp" && product.Version < "2.0" {
		fmt.Println("enabling compatibility mode for", product)
	}
}

accept := httpheader.Accept(r.Header)
acceptJSON := httpheader.MatchAccept(accept, "application/json")
acceptXML := httpheader.MatchAccept(accept, "text/xml")
if acceptXML.Q > acceptJSON.Q {
	fmt.Println("responding with XML")
}

// Output: received request from user at 198.51.100.30
// enabling compatibility mode for {MyApp 1.2.3 }
// responding with XML

Documentation

Overview

Package httpheader parses and generates standard HTTP headers.

For each header Foo-Bar covered by this package, there is a function FooBar to parse it, SetFooBar to generate it, and sometimes AddFooBar to append to it. Note that AddFooBar creates a new Foo-Bar header line (like http.Header's Add method), which, although correct, is poorly supported by some recipients.

FooBar parses all valid Foo-Bar headers, but many invalid headers are also tolerated and parsed to some extent. FooBar never errors, instead returning whatever it can easily salvage. Do not assume that strings returned by FooBar conform to the grammar of the protocol.

Likewise, SetFooBar doesn't validate parameter names or other tokens you supply. However, it will automatically quote and escape your text where the grammar admits an arbitrary quoted string or comment (RFC 7230 Section 3.2.6), such as in parameter values.

Tokens that are known to be case-insensitive, like directive or parameter names, are lowercased by FooBar, unless documented otherwise. Any maps returned by FooBar may be nil when there is no corresponding data.

Example
package main

import (
	"bufio"
	"fmt"
	"net/http"
	"strings"

	"github.com/vfaronov/httpheader"
)

func main() {
	const request = `GET / HTTP/1.1
Host: api.example.com
User-Agent: MyApp/1.2.3 python-requests/2.22.0
Accept: text/*, application/json;q=0.8
Forwarded: for="198.51.100.30:14852";by="[2001:db8::ae:56]";proto=https

`

	r, _ := http.ReadRequest(bufio.NewReader(strings.NewReader(request)))

	forwarded := httpheader.Forwarded(r.Header)
	fmt.Println("received request from user at", forwarded[0].For.IP)

	for _, product := range httpheader.UserAgent(r.Header) {
		if product.Name == "MyApp" && product.Version < "2.0" {
			fmt.Println("enabling compatibility mode for", product)
		}
	}

	accept := httpheader.Accept(r.Header)
	acceptJSON := httpheader.MatchAccept(accept, "application/json")
	acceptXML := httpheader.MatchAccept(accept, "text/xml")
	if acceptXML.Q > acceptJSON.Q {
		fmt.Println("responding with XML")
	}

}
Output:

received request from user at 198.51.100.30
enabling compatibility mode for {MyApp 1.2.3 }
responding with XML

Index

Examples

Constants

This section is empty.

Variables

View Source
var AnyTag = EntityTag{/* contains filtered or unexported fields */}

AnyTag represents a wildcard (*) in an If-Match or If-None-Match header.

View Source
var Eternity = Delta{1<<31 - 1, true}

Eternity represents unlimited age for the max-stale cache directive.

Functions

func AddForwarded

func AddForwarded(h http.Header, elems ...ForwardedElem)

AddForwarded is like SetForwarded but appends instead of replacing.

Example
header := http.Header{}
AddForwarded(header, ForwardedElem{
	For:   Node{IP: net.IPv4(203, 0, 113, 195)},
	Proto: "https",
})
header.Write(os.Stdout)
Output:

Forwarded: for=203.0.113.195;proto=https
func AddLink(h http.Header, links ...LinkElem)

AddLink is like SetLink but appends instead of replacing.

func AddVary

func AddVary(h http.Header, names ...string)

AddVary appends the given names to the Vary header in h (RFC 7231 Section 7.1.4).

func AddVia

func AddVia(h http.Header, elems ...ViaElem)

AddVia is like SetVia but appends instead of replacing.

Example
header := http.Header{}
AddVia(header, ViaElem{ReceivedProto: "HTTP/1.1", ReceivedBy: "api-gw1"})
header.Write(os.Stdout)
Output:

Via: 1.1 api-gw1

func AddWarning

func AddWarning(h http.Header, elems ...WarningElem)

AddWarning is like SetWarning but appends instead of replacing.

Example
header := http.Header{}
AddWarning(header, WarningElem{Code: 299, Text: "this service is deprecated"})
header.Write(os.Stdout)
Output:

Warning: 299 - "this service is deprecated"

func Allow

func Allow(h http.Header) []string

Allow parses the Allow header from h (RFC 7231 Section 7.4.1).

If there is no such header in h, Allow returns nil. If the header is present but empty (meaning all methods are disallowed), Allow returns a non-nil slice of length 0.

func ContentDisposition

func ContentDisposition(h http.Header) (dtype, filename string, params map[string]string)

ContentDisposition parses the Content-Disposition header from h (RFC 6266), returning the disposition type, the value of the 'filename' parameter (if any), and a map of any other parameters.

Any 'filename*' parameter is decoded from RFC 8187 encoding, and overrides 'filename'. Similarly for any other parameter whose name ends in an asterisk. UTF-8 is not validated in such strings.

Example
header := http.Header{"Content-Disposition": {
	`Attachment; filename="EURO rates"; filename*=utf-8''%e2%82%ac%20rates`,
}}
dtype, filename, _ := ContentDisposition(header)
fmt.Println(dtype)
fmt.Println(filename)
Output:

attachment
€ rates

func ContentType

func ContentType(h http.Header) (mtype string, params map[string]string)

ContentType parses the Content-Type header from h (RFC 7231 Section 3.1.1.5), returning the media type/subtype and any parameters.

func DecodeExtValue

func DecodeExtValue(v string) (text, lang string, err error)

DecodeExtValue decodes the given ext-value (RFC 8187) into its text and language tag, both of which may be empty. Only ext-values marked as UTF-8 are supported, and the actual decoded UTF-8 is not validated.

func EncodeExtValue

func EncodeExtValue(text, lang string) string

EncodeExtValue encodes text, which must be valid UTF-8, into an ext-value (RFC 8187) with the given lang tag. Both text and lang may be empty.

func Match

func Match(clientTags []EntityTag, serverTag EntityTag) bool

Match returns true if serverTag is equivalent to any of clientTags by strong comparison (RFC 7232 Section 2.3.2), as necessary for interpreting the If-Match header. For If-None-Match, use MatchWeak instead.

func MatchWeak

func MatchWeak(clientTags []EntityTag, serverTag EntityTag) bool

MatchWeak returns true if serverTag is equivalent to any of clientTags by weak comparison (RFC 7232 Section 2.3.2), as necessary for interpreting the If-None-Match header. For If-Match, use Match instead.

func Prefer

func Prefer(h http.Header) map[string]Pref

Prefer parses the Prefer header from h (RFC 7240), returning a map where keys are preference names.

Example
header := http.Header{"Prefer": []string{
	"wait=10, respond-async",
	`check-spelling; lang="en-US, en-GB"`,
}}
prefer := Prefer(header)
fmt.Printf("%+v\n%+v\n%+v\n",
	prefer["wait"],
	prefer["respond-async"],
	prefer["check-spelling"],
)
Output:

{Value:10 Params:map[]}
{Value: Params:map[]}
{Value: Params:map[lang:en-US, en-GB]}

func PreferenceApplied

func PreferenceApplied(h http.Header) map[string]string

PreferenceApplied parses the Preference-Applied header from h (RFC 7240 Section 3), returning a map where keys are preference names.

func RetryAfter

func RetryAfter(h http.Header) time.Time

RetryAfter parses the Retry-After header from h (RFC 7231 Section 7.1.3). When it is specified as delay seconds, those are added to the Date header if one exists in h, otherwise to the current time. If the header cannot be parsed, a zero Time is returned.

Example
header := http.Header{
	"Date":        {"Sun, 07 Jul 2019 08:03:32 GMT"},
	"Retry-After": {"180"},
}
fmt.Print(RetryAfter(header))
Output:

2019-07-07 08:06:32 +0000 UTC

func SetAccept

func SetAccept(h http.Header, elems []AcceptElem)

SetAccept replaces the Accept header in h (RFC 7231 Section 5.3.2).

Q in elems must be set explicitly to avoid sending "q=0", which would mean "not acceptable".

Example
header := http.Header{}
SetAccept(header, []AcceptElem{
	{Type: "application/json", Q: 1},
	{Type: "*/*", Q: 0.1},
})
header.Write(os.Stdout)
Output:

Accept: application/json, */*;q=0.1

func SetAllow

func SetAllow(h http.Header, methods []string)

SetAllow replaces the Allow header in h (RFC 7231 Section 7.4.1).

func SetAuthorization

func SetAuthorization(h http.Header, credentials Auth)

SetAuthorization replaces the Authorization header in h (RFC 7235 Section 4.2).

Example
header := http.Header{}
SetAuthorization(header, Auth{Scheme: "Bearer", Token: "wvmjsa9N0iyLjnFo"})
header.Write(os.Stdout)
Output:

Authorization: Bearer wvmjsa9N0iyLjnFo

func SetCacheControl

func SetCacheControl(h http.Header, cc CacheDirectives)

SetCacheControl replaces the Cache-Control header in h.

Example
header := http.Header{}
SetCacheControl(header, CacheDirectives{
	Public: true,
	MaxAge: DeltaSeconds(600),
	Ext:    map[string]string{"priority": "5"},
})
header.Write(os.Stdout)
Output:

Cache-Control: public, max-age=600, priority=5

func SetContentDisposition

func SetContentDisposition(h http.Header, dtype, filename string, params map[string]string)

SetContentDisposition replaces the Content-Disposition header in h (RFC 6266).

If filename is not empty, it must be valid UTF-8, which is serialized into a 'filename' parameter in plain ASCII, or a 'filename*' parameter in RFC 8187 encoding, or both, depending on what characters it contains.

Similarly, if params contains a 'qux' or 'qux*' key, it will be serialized into a 'qux' and/or 'qux*' parameter depending on its contents; the asterisk in the key is ignored. Any 'filename' or 'filename*' in params is skipped.

Example
header := http.Header{}
SetContentDisposition(header, "attachment", "Résumé.docx", nil)
header.Write(os.Stdout)
Output:

Content-Disposition: attachment; filename*=UTF-8''R%C3%A9sum%C3%A9.docx

func SetContentType

func SetContentType(h http.Header, mtype string, params map[string]string)

SetContentType replaces the Content-Type header in h (RFC 7231 Section 3.1.1.5).

func SetETag

func SetETag(h http.Header, tag EntityTag)

SetETag replaces the ETag header in h (RFC 7232 Section 2.3).

This package does not provide a function to parse ETag, only to set it. Parsing an ETag is of no use to most clients, and can hamper interoperability, because many servers in the wild send malformed ETags without double quotes. Instead, clients should treat ETags as opaque strings, and blindly join them with commas for If-Match/If-None-Match.

func SetForwarded

func SetForwarded(h http.Header, elems []ForwardedElem)

SetForwarded replaces the Forwarded header in h (RFC 7239). See also AddForwarded.

func SetLink(h http.Header, links []LinkElem)

SetLink replaces the Link header in h (RFC 8288). See also AddLink.

The Title of each LinkElem, if non-empty, is serialized into a 'title' parameter in quoted-string form, or a 'title*' parameter in RFC 8187 encoding, or both, depending on what characters it contains. Title should be valid UTF-8.

Similarly, if Ext contains a 'qux' or 'qux*' key, it will be serialized into a 'qux' and/or 'qux*' parameter depending on its contents; the asterisk in the key is ignored.

Any members of Ext named like corresponding fields of LinkElem, such as 'title*' or 'hreflang', are skipped.

func SetPrefer

func SetPrefer(h http.Header, prefs map[string]Pref)

SetPrefer replaces the Prefer header in h (RFC 7240).

Example
header := http.Header{}
SetPrefer(header, map[string]Pref{
	"wait":           {Value: "10"},
	"respond-async":  {},
	"check-spelling": {Params: map[string]string{"lang": "en"}},
})
Output:

func SetPreferenceApplied

func SetPreferenceApplied(h http.Header, prefs map[string]string)

SetPreferenceApplied replaces the Preference-Applied header in h (RFC 7240 Section 3).

func SetProxyAuthenticate

func SetProxyAuthenticate(h http.Header, challenges []Auth)

SetProxyAuthenticate replaces the Proxy-Authenticate header in h (RFC 7235 Section 4.3).

func SetProxyAuthorization

func SetProxyAuthorization(h http.Header, credentials Auth)

SetProxyAuthorization replaces the Proxy-Authorization header in h (RFC 7235 Section 4.4).

func SetRetryAfter

func SetRetryAfter(h http.Header, after time.Time)

SetRetryAfter replaces the Retry-After header in h (RFC 7231 Section 7.1.3).

func SetServer

func SetServer(h http.Header, products []Product)

SetServer replaces the Server header in h (RFC 7231 Section 7.4.2).

func SetUserAgent

func SetUserAgent(h http.Header, products []Product)

SetUserAgent replaces the User-Agent header in h (RFC 7231 Section 5.5.3).

Example
header := http.Header{}
SetUserAgent(header, []Product{
	{Name: "My-App", Version: "1.2.3", Comment: "example.com"},
	{Name: "Go-http-client"},
})
header.Write(os.Stdout)
Output:

User-Agent: My-App/1.2.3 (example.com) Go-http-client

func SetVary

func SetVary(h http.Header, names map[string]bool)

SetVary replaces the Vary header in h (RFC 7231 Section 7.1.4). Names mapping to false are ignored. See also AddVary.

func SetVia

func SetVia(h http.Header, elems []ViaElem)

SetVia replaces the Via header in h (RFC 7230 Section 5.7.1). See also AddVia.

func SetWWWAuthenticate

func SetWWWAuthenticate(h http.Header, challenges []Auth)

SetWWWAuthenticate replaces the WWW-Authenticate header in h (RFC 7235 Section 4.1).

Example
header := http.Header{}
SetWWWAuthenticate(header, []Auth{{
	Scheme: "Bearer",
	Realm:  "api.example.com",
	Params: map[string]string{"scope": "profile"},
}})
header.Write(os.Stdout)
Output:

Www-Authenticate: Bearer realm="api.example.com", scope=profile

func SetWarning

func SetWarning(h http.Header, elems []WarningElem)

SetWarning replaces the Warning header in h (RFC 7234 Section 5.5). See also AddWarning.

func Vary

func Vary(h http.Header) map[string]bool

Vary parses the Vary header from h (RFC 7231 Section 7.1.4), returning a map where keys are header names, canonicalized with http.CanonicalHeaderKey, and values are all true. A wildcard (Vary: *) is returned as map[*:true], so it must be checked explicitly.

Example
header := http.Header{"Vary": {"cookie, accept-encoding"}}
vary := Vary(header)
if vary["Accept-Encoding"] || vary["*"] {
	fmt.Println("response depends on the client's encoding support")
}
Output:

response depends on the client's encoding support

Types

type AcceptElem

type AcceptElem struct {
	Type   string            // media range
	Params map[string]string // media type parameters (before q)
	Q      float32           // quality value
	Ext    map[string]string // extension parameters (after q)
}

An AcceptElem represents one element of the Accept header (RFC 7231 Section 5.3.2).

func Accept

func Accept(h http.Header) []AcceptElem

Accept parses the Accept header from h (RFC 7231 Section 5.3.2). The function MatchAccept is useful for working with the returned slice.

Example
header := http.Header{"Accept": {"text/html, text/*;q=0.1"}}
accept := Accept(header)
fmt.Println(MatchAccept(accept, "text/html").Q)
fmt.Println(MatchAccept(accept, "text/plain").Q)
fmt.Println(MatchAccept(accept, "image/gif").Q)
Output:

1
0.1
0

func MatchAccept

func MatchAccept(accept []AcceptElem, mediaType string) AcceptElem

MatchAccept searches accept for the element that most closely matches mediaType, according to precedence rules of RFC 7231 Section 5.3.2. Only the bare type/subtype can be matched with this function; elements with Params are not considered. If nothing matches mediaType, a zero AcceptElem is returned.

type Auth

type Auth struct {
	Scheme string
	Token  string
	Realm  string
	Params map[string]string
}

Auth represents an authentication challenge or credentials (RFC 7235 Section 2.1). When using the token68 form, the Token field is non-zero. When using the auth-param form, the Realm and/or Params fields are non-zero. Realm is the value of the 'realm' parameter, if any. Sending an empty realm="" is not supported, and any 'realm' key in Params is ignored.

"Star" parameters like RFC 7616's 'username*' are not treated specially. Call DecodeExtValue and EncodeExtValue manually if needed.

Scheme names are case-insensitive according to RFC 7235, but many implementations erroneously expect them to be in their canonical spelling as given in https://www.iana.org/assignments/http-authschemes/. Because of this, all functions returning Auth lowercase the Scheme, but all functions serializing Auth transform a lowercase Scheme into its canonical spelling, or to strings.Title for unknown schemes. If you supply a non-lowercase Scheme, its spelling will be preserved.

func Authorization

func Authorization(h http.Header) Auth

Authorization parses the Authorization header from h (RFC 7235 Section 4.2). If h doesn't contain Authorization, a zero Auth is returned.

func ProxyAuthenticate

func ProxyAuthenticate(h http.Header) []Auth

ProxyAuthenticate parses the Proxy-Authenticate header from h (RFC 7235 Section 4.3).

func ProxyAuthorization

func ProxyAuthorization(h http.Header) Auth

ProxyAuthorization parses the Proxy-Authorization header from h (RFC 7235 Section 4.4). If h doesn't contain Proxy-Authorization, a zero Auth is returned.

func WWWAuthenticate

func WWWAuthenticate(h http.Header) []Auth

WWWAuthenticate parses the WWW-Authenticate header from h (RFC 7235 Section 4.1).

type CacheDirectives

type CacheDirectives struct {
	NoStore         bool
	NoTransform     bool
	OnlyIfCached    bool
	MustRevalidate  bool
	Public          bool
	ProxyRevalidate bool
	Immutable       bool // RFC 8246

	// NoCache is true if the no-cache directive is present without an argument.
	// If it has an argument -- a list of header names -- these are
	// stored in NoCacheHeaders, canonicalized with http.CanonicalHeaderKey;
	// while NoCache remains false. Similarly for the private directive.
	NoCache        bool
	Private        bool
	NoCacheHeaders []string
	PrivateHeaders []string

	MaxAge               Delta
	SMaxage              Delta
	MinFresh             Delta
	StaleWhileRevalidate Delta // RFC 5861 Section 3
	StaleIfError         Delta // RFC 5861 Section 4

	// A max-stale directive without an argument (meaning "any age")
	// is represented as the special very large value Eternity.
	MaxStale Delta

	// Any unknown extension directives.
	// A key mapping to an empty string is serialized to a directive
	// without an argument.
	Ext map[string]string
}

CacheDirectives represents directives of the Cache-Control header (RFC 7234 Section 5.2). Standard directives are stored in the corresponding fields; any unknown extensions are stored in Ext.

func CacheControl

func CacheControl(h http.Header) CacheDirectives

CacheControl parses the Cache-Control header from h (RFC 7234 Section 5.2).

Example
ourAge := time.Duration(10) * time.Minute
header := http.Header{"Cache-Control": {"max-age=300, must-revalidate"}}
cc := CacheControl(header)
if maxAge, ok := cc.MaxAge.Value(); ok && ourAge > maxAge {
	fmt.Println("our copy is stale")
}
Output:

our copy is stale

type Delta

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

A Delta represents a numeric cache directive which may be either absent or a number of seconds. The zero value of Delta is the absent value, not 0 seconds.

func DeltaSeconds

func DeltaSeconds(s int) Delta

DeltaSeconds returns a Delta of the given number of seconds.

func (Delta) Value

func (d Delta) Value() (dur time.Duration, ok bool)

Value returns the duration of d if it is present; otherwise 0, false.

type EntityTag

type EntityTag struct {
	Weak   bool
	Opaque string // not including double quotes
	// contains filtered or unexported fields
}

An EntityTag is an opaque entity tag (RFC 7232 Section 2.3).

func IfMatch

func IfMatch(h http.Header) []EntityTag

IfMatch parses the If-Match header from h (RFC 7232 Section 3.1). A wildcard (If-Match: *) is returned as the special AnyTag value.

The function Match is useful for working with the returned slice.

There is no SetIfMatch function; see comment on SetETag.

func IfNoneMatch

func IfNoneMatch(h http.Header) []EntityTag

IfNoneMatch parses the If-None-Match header from h (RFC 7232 Section 3.2). A wildcard (If-None-Match: *) is returned as the special AnyTag value.

The function MatchWeak is useful for working with the returned slice.

There is no SetIfNoneMatch function; see comment on SetETag.

Example
serverTag := EntityTag{Weak: true, Opaque: "v.62"}
request := http.Header{"If-None-Match": {`W/"v.57", W/"v.62", "f09a3ccd"`}}
response := http.Header{}
if MatchWeak(IfNoneMatch(request), serverTag) {
	fmt.Println("Status: 304 Not Modified")
	SetETag(response, serverTag)
	return
}
fmt.Println("Status: 200 OK")
SetETag(response, serverTag)
Output:

Status: 304 Not Modified

type ForwardedElem

type ForwardedElem struct {
	By    Node
	For   Node
	Host  string
	Proto string
	Ext   map[string]string
}

A ForwardedElem represents one element of the Forwarded header (RFC 7239). Standard parameters are stored in the corresponding fields; any extension parameters are stored in Ext.

func Forwarded

func Forwarded(h http.Header) []ForwardedElem

Forwarded parses the Forwarded header from h (RFC 7239).

Do not trust the returned values for sensitive purposes such as access control, unless you have a trusted gateway controlling the Forwarded header. This header's syntax makes it possible for a malicious client to submit a malformed value that will "shadow" further elements appended to the same value.

Example
header := http.Header{"Forwarded": {
	`for=192.0.2.61;by="[2001:db8::fa40]";proto=https`,
	`for="[2001:db8::fa40]:19950";proto=http`,
}}
for _, elem := range Forwarded(header) {
	fmt.Println(elem.For.IP)
}
Output:

192.0.2.61
2001:db8::fa40

type LinkElem

type LinkElem struct {
	Anchor   *url.URL // usually nil
	Rel      string
	Target   *url.URL // always non-nil
	Title    string
	Type     string
	HrefLang []string
	Media    string
	Ext      map[string]string
}

A LinkElem represents a Web link (RFC 8288). Standard target attributes are stored in the corresponding fields; any extension attributes are stored in Ext.

func Link(h http.Header, base *url.URL) []LinkElem

Link parses the Link header from h (RFC 8288), resolving any relative Target and Anchor URLs against base, which is the URL that h was obtained from (http.Response's Request.URL).

In general, callers should check the Anchor of each returned LinkElem: a non-nil Anchor indicates a link pointing "from" another context (not the one that supplied the Link header). See RFC 8288 Section 3.2.

Any 'title*' parameter is decoded from RFC 8187 encoding, and overrides 'title'. Similarly for any extension attribute whose name ends in an asterisk. UTF-8 is not validated in such strings.

When the header contains multiple relation types in one value, like rel="next prefetch", multiple LinkElems with different Rel are returned. Any 'rev' parameter is discarded.

type Node

type Node struct {
	IP             net.IP
	Port           int
	ObfuscatedNode string
	ObfuscatedPort string
}

A Node represents a node identifier in a Forwarded header (RFC 7239 Section 6). Either IP or ObfuscatedNode may be non-zero, but not both. Similarly for Port and ObfuscatedPort.

type Pref

type Pref struct {
	Value  string
	Params map[string]string
}

A Pref contains a preference's value and any associated parameters (RFC 7240).

type Product

type Product struct {
	Name    string
	Version string
	Comment string
}

A Product contains software information as found in the User-Agent and Server headers (RFC 7231 Section 5.5.3 and Section 7.4.2). If multiple comments are associated with a product, they are concatenated with a "; " separator.

func Server

func Server(h http.Header) []Product

Server parses the Server header from h (RFC 7231 Section 7.4.2).

func UserAgent

func UserAgent(h http.Header) []Product

UserAgent parses the User-Agent header from h (RFC 7231 Section 5.5.3).

type ViaElem

type ViaElem struct {
	ReceivedProto string
	ReceivedBy    string
	Comment       string
}

A ViaElem represents one element of the Via header (RFC 7230 Section 5.7.1).

func Via

func Via(h http.Header) []ViaElem

Via parses the Via header from h (RFC 7230 Section 5.7.1).

ReceivedProto in returned elements is canonicalized to always include name: “1.1” becomes “HTTP/1.1”. As a special case, “2” and “HTTP/2” become “HTTP/2.0”.

BUG(vfaronov): Incorrectly parses some extravagant values of uri-host that do not occur in practice but are theoretically admitted by RFC 3986.

Example
header := http.Header{"Via": {
	"1.1 proxy2.example.com:8080 (corporate)",
	"2 edge3.example.net",
}}
fmt.Print(Via(header))
Output:

[{HTTP/1.1 proxy2.example.com:8080 corporate} {HTTP/2.0 edge3.example.net }]

type WarningElem

type WarningElem struct {
	Code  int
	Agent string // defaults to "-" on output
	Text  string
	Date  time.Time // zero if missing
}

A WarningElem represents one element of the Warning header (RFC 7234 Section 5.5).

func Warning

func Warning(h http.Header) []WarningElem

Warning parses the Warning header from h (RFC 7234 Section 5.5).

Notes

Bugs

  • Incorrectly parses some extravagant values of uri-host that do not occur in practice but are theoretically admitted by RFC 3986.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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