-
Notifications
You must be signed in to change notification settings - Fork 350
/
inlinecontentifstatus.go
93 lines (76 loc) · 2.15 KB
/
inlinecontentifstatus.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
88
89
90
91
92
93
package builtin
import (
"bytes"
"io"
"net/http"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/zalando/skipper/filters"
)
type inlineContentIfStatus struct {
statusCode int
text string
mime string
}
// Creates a filter spec for the inlineContent() filter.
//
// * -> inlineContentIfStatus(401, "{\"foo\": 42}", "application/json") -> "https://www.example.org"
//
// It accepts three arguments: the statusCode code to match, the content and the optional content type.
// When the content type is not set, it tries to detect it using http.DetectContentType.
//
// The filter replaces the response coming from the backend or the following filters.
//
func NewInlineContentIfStatus() filters.Spec {
return &inlineContentIfStatus{}
}
func (c *inlineContentIfStatus) Name() string { return filters.InlineContentIfStatusName }
func (c *inlineContentIfStatus) CreateFilter(args []interface{}) (filters.Filter, error) {
if len(args) < 2 || len(args) > 3 {
return nil, filters.ErrInvalidFilterParameters
}
var (
f inlineContentIfStatus
ok bool
)
f.statusCode, ok = args[0].(int)
if !ok {
floatStatusCode, ok := args[0].(float64)
if !ok {
return nil, filters.ErrInvalidFilterParameters
}
f.statusCode = int(floatStatusCode)
}
if f.statusCode < 100 || f.statusCode >= 600 {
return nil, filters.ErrInvalidFilterParameters
}
f.text, ok = args[1].(string)
if !ok {
return nil, filters.ErrInvalidFilterParameters
}
if len(args) == 3 {
f.mime, ok = args[2].(string)
if !ok {
return nil, filters.ErrInvalidFilterParameters
}
} else {
f.mime = http.DetectContentType([]byte(f.text))
}
return &f, nil
}
func (c *inlineContentIfStatus) Request(filters.FilterContext) {}
func (c *inlineContentIfStatus) Response(ctx filters.FilterContext) {
if ctx.Response().StatusCode != c.statusCode {
return
}
rsp := ctx.Response()
err := rsp.Body.Close()
if err != nil {
log.Error(err)
}
contentLength := len(c.text)
rsp.ContentLength = int64(contentLength)
rsp.Header.Set("Content-Type", c.mime)
rsp.Header.Set("Content-Length", strconv.Itoa(contentLength))
rsp.Body = io.NopCloser(bytes.NewBufferString(c.text))
}