73 lines
1.4 KiB
Go
73 lines
1.4 KiB
Go
package libhttp
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/gobwas/glob"
|
|
"go.opentelemetry.io/otel/trace"
|
|
)
|
|
|
|
func Accepts(r *http.Request, defaultAccept string, validAccepts ...string) (string, int, error) {
|
|
_, t := tracer.Start(r.Context(), "Accepts", trace.WithSpanKind(trace.SpanKindInternal))
|
|
defer t.End()
|
|
|
|
accept := r.Header.Get(HeaderAccept)
|
|
if accept == "" {
|
|
return defaultAccept, http.StatusOK, nil
|
|
}
|
|
|
|
types := strings.Split(accept, ",")
|
|
|
|
mime := ""
|
|
acceptList := make([]string, len(types))
|
|
q := float64(0)
|
|
for i, t := range types {
|
|
params := strings.Split(t, ";")
|
|
foundMime := strings.TrimSpace(params[0])
|
|
|
|
acceptList[i] = foundMime
|
|
|
|
foundQ, err := findQ(params)
|
|
if err != nil {
|
|
return "", http.StatusBadRequest, ErrMalformedAccept
|
|
}
|
|
|
|
g, err := glob.Compile(foundMime)
|
|
if err != nil {
|
|
return "", http.StatusBadRequest, ErrMalformedAccept
|
|
}
|
|
|
|
for _, a := range validAccepts {
|
|
if g.Match(a) {
|
|
if foundQ > q {
|
|
mime = a
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if mime == "" {
|
|
return "", http.StatusNotAcceptable, fmt.Errorf("media-type %s unsupported", strings.Join(acceptList, ", "))
|
|
}
|
|
|
|
return mime, 0, nil
|
|
}
|
|
|
|
func findQ(a []string) (float64, error) {
|
|
if len(a) == 1 {
|
|
return 1.0, nil
|
|
}
|
|
|
|
for i := 1; i < len(a); i++ {
|
|
parts := strings.Split(strings.TrimSpace(a[i]), "=")
|
|
if len(parts) == 2 && parts[0] == "q" {
|
|
return strconv.ParseFloat(parts[1], 64)
|
|
}
|
|
}
|
|
|
|
return 1.0, nil
|
|
}
|