forked from seborama/govcr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathresponse.go
136 lines (120 loc) · 3.68 KB
/
response.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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package govcr
import (
"net/http"
"regexp"
)
// ResponseFilter is a hook function that is used to filter the Response Header / Body.
//
// It works similarly to RequestFilterFunc but applies to the Response and also receives a
// copy of the Request context (if you need to pick info from it to override the response).
//
// Return the modified response.
type ResponseFilter func(resp Response) Response
// ResponseFilters is a slice of ResponseFilter
type ResponseFilters []ResponseFilter
// Response provides the response parameters.
// When returned from a ResponseFilter these values will be returned instead.
type Response struct {
req Request
// The content returned in the response.
Body []byte
Header http.Header
StatusCode int
}
// Request returns the request.
// This is the request after RequestFilters have been applied.
func (r Response) Request() Request {
// Copied to avoid modifications.
return r.req
}
// ResponseAddHeaderValue will add/overwrite a header to the response when it is returned from vcr playback.
func ResponseAddHeaderValue(key, value string) ResponseFilter {
return func(resp Response) Response {
resp.Header.Add(key, value)
return resp
}
}
// ResponseDeleteHeaderKeys will delete one or more headers on the response when returned from vcr playback.
func ResponseDeleteHeaderKeys(keys ...string) ResponseFilter {
return func(resp Response) Response {
for _, key := range keys {
resp.Header.Del(key)
}
return resp
}
}
// ResponseTransferHeaderKeys will transfer one or more header from the Request to the Response.
func ResponseTransferHeaderKeys(keys ...string) ResponseFilter {
return func(resp Response) Response {
for _, key := range keys {
resp.Header.Add(key, resp.req.Header.Get(key))
}
return resp
}
}
// ResponseChangeBody will allows to change the body.
// Supply a function that does input to output transformation.
func ResponseChangeBody(fn func(b []byte) []byte) ResponseFilter {
return func(resp Response) Response {
resp.Body = fn(resp.Body)
return resp
}
}
// OnMethod will return a Response filter that will only apply 'r'
// if the method of the response matches.
// Original filter is unmodified.
func (r ResponseFilter) OnMethod(method string) ResponseFilter {
return func(resp Response) Response {
if resp.req.Method != method {
return resp
}
return r(resp)
}
}
// OnPath will return a Response filter that will only apply 'r'
// if the url string of the Response matches the supplied regex.
// Original filter is unmodified.
func (r ResponseFilter) OnPath(pathRegEx string) ResponseFilter {
if pathRegEx == "" {
pathRegEx = ".*"
}
re := regexp.MustCompile(pathRegEx)
return func(resp Response) Response {
if !re.MatchString(resp.req.URL.String()) {
return resp
}
return r(resp)
}
}
// OnStatus will return a Response filter that will only apply 'r' if the response status matches.
// Original filter is unmodified.
func (r ResponseFilter) OnStatus(status int) ResponseFilter {
return func(resp Response) Response {
if resp.StatusCode != status {
return resp
}
return r(resp)
}
}
// Add one or more filters at the end of the filter chain.
func (r *ResponseFilters) Add(filters ...ResponseFilter) {
v := *r
v = append(v, filters...)
*r = v
}
// Prepend one or more filters before the current ones.
func (r *ResponseFilters) Prepend(filters ...ResponseFilter) {
src := *r
dst := make(ResponseFilters, 0, len(filters)+len(src))
dst = append(dst, filters...)
*r = append(dst, src...)
}
// combined returns the filters as a single filter.
func (r ResponseFilters) combined() ResponseFilter {
return func(resp Response) Response {
for _, filter := range r {
resp = filter(resp)
}
return resp
}
}