-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathvcr.go
91 lines (73 loc) · 2.16 KB
/
vcr.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
package vcr
import (
"net/http"
)
const (
modeRecord = iota
modeReplay
)
// RequestModifierFunc is a function that can be used to manipulate HTTP requests
// before they are sent to the server.
// Useful for adding row-limits in integration tests.
type RequestModifierFunc func(request *http.Request)
var currentFilterMap map[string]string
var currentRequestModifier RequestModifierFunc
var currentMode = modeRecord
var currentCassette *cassette
type roundTripper struct {
originalRT http.RoundTripper
}
func init() {
http.DefaultTransport = &roundTripper{originalRT: http.DefaultTransport}
}
// Start starts a VCR session with the given cassette name.
// Records episodes if the cassette file does not exists.
// Otherwise plays back recorded episodes.
func Start(cassetteName string, modFunc RequestModifierFunc) {
if currentCassette != nil {
panic("VCR: Session already started!")
}
currentCassette = &cassette{name: cassetteName}
currentRequestModifier = modFunc
currentFilterMap = make(map[string]string)
if currentCassette.exists() {
currentMode = modeReplay
currentCassette.read()
} else {
currentMode = modeRecord
}
}
// FilterData allows replacement of sensitive data with a dummy-string
func FilterData(original string, replacement string) {
currentFilterMap[original] = replacement
}
// Stop stops the VCR session and writes the cassette file (when recording)
func Stop() {
if currentMode == modeRecord {
currentCassette.write()
}
currentCassette = nil
}
func (rt *roundTripper) RoundTrip(request *http.Request) (*http.Response, error) {
vcrReq := newVCRRequest(request, currentFilterMap)
var vcrRes *vcrResponse
if currentCassette == nil {
return rt.originalRT.RoundTrip(request)
}
if currentRequestModifier != nil {
currentRequestModifier(request)
}
if currentMode == modeRecord {
response, err := rt.originalRT.RoundTrip(request)
if err != nil {
return nil, err
}
vcrRes = newVCRResponse(response)
e := episode{Request: vcrReq, Response: vcrRes}
currentCassette.Episodes = append(currentCassette.Episodes, e)
} else {
e := currentCassette.matchEpisode(vcrReq)
vcrRes = e.Response
}
return vcrRes.httpResponse(), nil
}