-
Notifications
You must be signed in to change notification settings - Fork 3
/
renderer.go
45 lines (39 loc) · 1.75 KB
/
renderer.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
package torque
import (
"fmt"
"github.com/pkg/errors"
"net/http"
)
var (
// ErrRenderFnNotDefined is returned by VaryRender when the given header value is not
// found in the given cases map and a default case is not provided.
ErrRenderFnNotDefined = errors.New("render function not defined for header value")
)
// RenderFn is a function that renders a response to the given http.ResponseWriter.
type RenderFn = func(wr http.ResponseWriter, req *http.Request) error
// VaryDefault is a special key that can be used in the cases map of VaryRender to
// indicate that the given RenderFn should be used as the default case.
const VaryDefault key = "default"
// VaryRender is a helper function for rendering different responses based on the given
// header key. The header key is used to look up a RenderFn in the given cases map.
//
// Sometimes it is useful to have a default case that is used when the header value is not
// found in the map. To do this, add VaryDefault as the key in the case map.
//
// If the header value is not found in the map and a default is not provided, then VaryRender
// returns ErrRenderFnNotDefined.
//
// The given header is also written to the Vary header of the response to indicate to the
// browser cache that responses from this endpoint may vary.
func VaryRender(wr http.ResponseWriter, req *http.Request, header string, cases map[any]RenderFn) error {
// Tell the cache that the response can vary based on the request header
wr.Header().Set("Vary", header)
value := req.Header.Get(header)
if fn, ok := cases[value]; ok {
return fn(wr, req)
} else if fn, ok := cases[VaryDefault]; ok {
return fn(wr, req)
} else {
return errors.WithMessage(ErrRenderFnNotDefined, fmt.Sprintf("render function not found for header value %q", value))
}
}