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 ¶
- Variables
- func AddForwarded(h http.Header, elems ...ForwardedElem)
- func AddLink(h http.Header, links ...LinkElem)
- func AddVary(h http.Header, names ...string)
- func AddVia(h http.Header, elems ...ViaElem)
- func AddWarning(h http.Header, elems ...WarningElem)
- func Allow(h http.Header) []string
- func ContentDisposition(h http.Header) (dtype, filename string, params map[string]string)
- func ContentType(h http.Header) (mtype string, params map[string]string)
- func DecodeExtValue(v string) (text, lang string, err error)
- func EncodeExtValue(text, lang string) string
- func Match(clientTags []EntityTag, serverTag EntityTag) bool
- func MatchWeak(clientTags []EntityTag, serverTag EntityTag) bool
- func Prefer(h http.Header) map[string]Pref
- func PreferenceApplied(h http.Header) map[string]string
- func RetryAfter(h http.Header) time.Time
- func SetAccept(h http.Header, elems []AcceptElem)
- func SetAllow(h http.Header, methods []string)
- func SetAuthorization(h http.Header, credentials Auth)
- func SetCacheControl(h http.Header, cc CacheDirectives)
- func SetContentDisposition(h http.Header, dtype, filename string, params map[string]string)
- func SetContentType(h http.Header, mtype string, params map[string]string)
- func SetETag(h http.Header, tag EntityTag)
- func SetForwarded(h http.Header, elems []ForwardedElem)
- func SetLink(h http.Header, links []LinkElem)
- func SetPrefer(h http.Header, prefs map[string]Pref)
- func SetPreferenceApplied(h http.Header, prefs map[string]string)
- func SetProxyAuthenticate(h http.Header, challenges []Auth)
- func SetProxyAuthorization(h http.Header, credentials Auth)
- func SetRetryAfter(h http.Header, after time.Time)
- func SetServer(h http.Header, products []Product)
- func SetUserAgent(h http.Header, products []Product)
- func SetVary(h http.Header, names map[string]bool)
- func SetVia(h http.Header, elems []ViaElem)
- func SetWWWAuthenticate(h http.Header, challenges []Auth)
- func SetWarning(h http.Header, elems []WarningElem)
- func Vary(h http.Header) map[string]bool
- type AcceptElem
- type Auth
- type CacheDirectives
- type Delta
- type EntityTag
- type ForwardedElem
- type LinkElem
- type Node
- type Pref
- type Product
- type ViaElem
- type WarningElem
- Bugs
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var AnyTag = EntityTag{/* contains filtered or unexported fields */}
AnyTag represents a wildcard (*) in an If-Match or If-None-Match header.
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 ¶
AddLink is like SetLink but appends instead of replacing.
Example ¶
header := http.Header{} AddLink(header, LinkElem{ Target: &url.URL{Path: "/articles/124"}, Rel: "next", Title: "Witaj świecie!", }) header.Write(os.Stdout)
Output: Link: </articles/124>; rel=next; title*=UTF-8''Witaj%20%C5%9Bwiecie!
func AddVary ¶
AddVary appends the given names to the Vary header in h (RFC 7231 Section 7.1.4).
func AddVia ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
PreferenceApplied parses the Preference-Applied header from h (RFC 7240 Section 3), returning a map where keys are preference names.
func RetryAfter ¶
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 ¶
SetAllow replaces the Allow header in h (RFC 7231 Section 7.4.1).
func SetAuthorization ¶
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 ¶
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 ¶
SetContentType replaces the Content-Type header in h (RFC 7231 Section 3.1.1.5).
func SetETag ¶
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 ¶
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 ¶
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 ¶
SetPreferenceApplied replaces the Preference-Applied header in h (RFC 7240 Section 3).
func SetProxyAuthenticate ¶
SetProxyAuthenticate replaces the Proxy-Authenticate header in h (RFC 7235 Section 4.3).
func SetProxyAuthorization ¶
SetProxyAuthorization replaces the Proxy-Authorization header in h (RFC 7235 Section 4.4).
func SetRetryAfter ¶
SetRetryAfter replaces the Retry-After header in h (RFC 7231 Section 7.1.3).
func SetServer ¶
SetServer replaces the Server header in h (RFC 7231 Section 7.4.2).
func SetUserAgent ¶
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 ¶
SetVary replaces the Vary header in h (RFC 7231 Section 7.1.4). Names mapping to false are ignored. See also AddVary.
func SetVia ¶
SetVia replaces the Via header in h (RFC 7230 Section 5.7.1). See also AddVia.
func SetWWWAuthenticate ¶
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 ¶
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 ¶
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 ¶
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 ¶
ProxyAuthenticate parses the Proxy-Authenticate header from h (RFC 7235 Section 4.3).
func ProxyAuthorization ¶
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 ¶
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 ¶
DeltaSeconds returns a Delta of the given number of seconds.
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 ¶
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 ¶
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 ¶
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 ¶
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.
Example ¶
// In real code, base := resp.Request.URL base, _ := url.Parse("https://api.example/articles/123") header := http.Header{"Link": { `</articles/124>; rel="next"; title*=utf-8''Witaj%20%C5%9Bwiecie!`, `<./>;rel=up, <https://api.example/doc>;rel=help;title="API help"`, }} links := Link(header, base) for _, link := range links { fmt.Printf("%-5s %-35s %q\n", link.Rel, link.Target, link.Title) }
Output: next https://api.example/articles/124 "Witaj świecie!" up https://api.example/articles/ "" help https://api.example/doc "API help"
type Node ¶
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 Product ¶
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 ¶
Server parses the Server header from h (RFC 7231 Section 7.4.2).
type ViaElem ¶
A ViaElem represents one element of the Via header (RFC 7230 Section 5.7.1).
func Via ¶
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).