Documentation ¶
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Acceptable ¶
type Acceptable struct { // The value that is acceptable for a response. May contain wildcard // ('*') characters. Value string // The quality, between 0 and 1, of the accepted value. // 0 is special and means "not acceptable" per RFC 9110. // Default quality is 1. Quality float32 // Params contains any extra optional parameters for this value. Params map[string]string }
Acceptable represents an acceptable value for a response; typical use is representing media (or MIME) type value as per RFC2616 §14.1 in an Accept header, as well as encoding (Accept-Encoding), language (Accept-Language), and character set (Accept-Charset).
func NegotiateContent ¶
NegotiateContent returns the best matching offer for the passed header, as well as the entry that it matched against. The best matching offer is determined by the first matching offer, in slice order, when iterating over the accepted media types by order of precedence.
If no offer matches, ("", nil) is returned.
Example ¶
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { ctype, _ := htutil.NegotiateContent(req.Header, "Accept", "text/plain", "application/json", ) if ctype == "" { w.WriteHeader(http.StatusNotAcceptable) return } w.Header().Set("Content-Type", ctype) w.WriteHeader(http.StatusOK) switch ctype { case "application/json": fmt.Fprint(w, `{"message":"OK"}`) case "text/plain": fmt.Fprint(w, `OK`) } }) server := http.Server{Addr: ":8080"} defer server.Shutdown(context.Background()) go server.ListenAndServe() get := func(addr, accept string) string { req, err := http.NewRequest("GET", addr, nil) if err != nil { log.Fatal(err) } req.Header.Set("Accept", accept) resp, err := http.DefaultClient.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close() if resp.StatusCode != 200 { return fmt.Sprintf("%d %s", resp.StatusCode, http.StatusText(resp.StatusCode)) } var out strings.Builder io.Copy(&out, resp.Body) return out.String() } fmt.Println(get("http://localhost:8080", "*/*")) fmt.Println(get("http://localhost:8080", "text/plain")) fmt.Println(get("http://localhost:8080", "application/json")) fmt.Println(get("http://localhost:8080", "text/html")) fmt.Println(get("http://localhost:8080", "application/json, text/*;q=0.5, */*;q=0.1")) fmt.Println(get("http://localhost:8080", ""))
Output: OK OK {"message":"OK"} 406 Not Acceptable {"message":"OK"} 406 Not Acceptable
func ParseAccept ¶
func ParseAccept(accepts ...string) []Acceptable
ParseAccept parses the accept header, and returns a list of acceptable values, sorted by precedence. Any unparseable value is silently dropped.
func ParseAcceptable ¶
func ParseAcceptable(v string) (Acceptable, error)
ParseAcceptable parses a single acceptable value, as laid out in an Accept{,-*} or Content-* header as per RFC2616 §14.1
func (Acceptable) Less ¶
func (lhs Acceptable) Less(rhs Acceptable) bool
Less is a comparison function for two Acceptables. lhs is less than rhs if:
- it has a quality factor that is less than rhs's quality factor
- or, if both quality factors are equal, it is more specific than rhs.
An Acceptable is more specific if its value does not contain patterns, and if it has additional parameters. For instance, given the following header:
Accept: text/*, text/html, text/html;level=1, */*
The types have the following precedence:
- text/html;level=1
- text/html
- text/*
- */*
func (Acceptable) String ¶
func (acc Acceptable) String() string
type URL ¶
URL embeds *url.URL, but implements encoding.TextMarshaler and encoding.TextUnmarshaler to simply call MarshalBinary and UnmarshalBinary respectively.
func (URL) MarshalText ¶
Example ¶
u, err := url.Parse("https://google.com") if err != nil { log.Fatal(err) } value := T{ URL: htutil.URL{u}, } txt, err := json.Marshal(value) if err != nil { log.Fatal(err) } fmt.Println(string(txt))
Output: {"url":"https://google.com"}