-
Notifications
You must be signed in to change notification settings - Fork 137
/
json_headers.go
87 lines (77 loc) · 2.44 KB
/
json_headers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package middlewares
import (
"net/http"
"strings"
"github.com/cozy/cozy-stack/pkg/jsonapi"
"github.com/labstack/echo/v4"
"github.com/golang/gddo/httputil"
)
const (
defaultContentTypeOffer = jsonapi.ContentType
acceptContentTypeKey = "offer-content-type"
)
var contentTypeOffers = []string{
jsonapi.ContentType,
echo.MIMEApplicationJSON,
echo.MIMETextHTML,
echo.MIMETextPlain,
}
// AcceptOptions can be used to parameterize the the Accept middleware: the
// default content-type in case no offer is accepted, and the list of offers to
// select from.
type AcceptOptions struct {
DefaultContentTypeOffer string
Offers []string
}
// AcceptJSON is an echo middleware that checks that the HTTP Accept header
// is compatible with application/json
func AcceptJSON(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
accept := c.Request().Header.Get(echo.HeaderAccept)
if accept == "*/*" || strings.Contains(accept, echo.MIMEApplicationJSON) {
return next(c)
}
return c.JSON(http.StatusBadRequest, echo.Map{
"error": "bad_accept_header",
})
}
}
// ContentTypeJSON is an echo middleware that checks that the HTTP Content-Type
// header is compatible with application/json
func ContentTypeJSON(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
contentType := c.Request().Header.Get(echo.HeaderContentType)
if strings.HasPrefix(contentType, echo.MIMEApplicationJSON) {
return next(c)
}
return c.JSON(http.StatusBadRequest, echo.Map{
"error": "bad_content_type",
})
}
}
// Accept is a middleware resolving the better content-type offering for the
// HTTP request, given the `Accept` header and the middleware options.
func Accept(args ...AcceptOptions) echo.MiddlewareFunc {
var opts AcceptOptions
if len(args) > 0 {
opts = args[0]
}
if opts.DefaultContentTypeOffer == "" {
opts.DefaultContentTypeOffer = defaultContentTypeOffer
}
if opts.Offers == nil {
opts.Offers = contentTypeOffers
}
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
contentTypeOffer := httputil.NegotiateContentType(c.Request(), opts.Offers, opts.DefaultContentTypeOffer)
c.Set(acceptContentTypeKey, contentTypeOffer)
return next(c)
}
}
}
// AcceptedContentType returns the accepted content-type store from the Accept
// middleware.
func AcceptedContentType(c echo.Context) string {
return c.Get(acceptContentTypeKey).(string)
}