-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathgovcr.go
125 lines (102 loc) · 3.87 KB
/
govcr.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
package govcr
import (
"fmt"
"net/http"
"os"
"github.com/seborama/govcr/v12/cassette"
"github.com/seborama/govcr/v12/encryption"
)
// CrypterProvider is the signature of a cipher provider function with default nonce generator.
// Examples are encryption.NewAESGCMWithRandomNonceGenerator and
// encryption.NewChaCha20Poly1305WithRandomNonceGenerator.
type CrypterProvider func(key []byte) (*encryption.Crypter, error)
// CrypterNonceProvider is the signature of a cipher provider function with custom nonce generator.
// Examples are encryption.NewAESGCM and encryption.NewChaCha20Poly1305.
type CrypterNonceProvider func(key []byte, nonceGenerator encryption.NonceGenerator) (*encryption.Crypter, error)
// CassetteLoader helps build a cassette to load in the VCR.
type CassetteLoader struct {
cassetteName string
opts []cassette.Option
}
// NewCassetteLoader creates a new CassetteLoader, initialised with the cassette's name.
func NewCassetteLoader(cassetteName string) *CassetteLoader {
return &CassetteLoader{
cassetteName: cassetteName,
}
}
// WithCipher creates a cassette cryptographer with the specified cipher function
// and key file.
// Using more than one WithCipher* on the same cassette is ambiguous.
func (cb *CassetteLoader) WithCipher(crypter CrypterProvider, keyFile string) *CassetteLoader {
f := func(key []byte, nonceGenerator encryption.NonceGenerator) (*encryption.Crypter, error) {
// a "CrypterProvider" is a CrypterNonceProvider with a pre-defined / default nonceGenerator
return crypter(key)
}
return cb.WithCipherCustomNonce(f, keyFile, nil)
}
// WithCipherCustomNonce creates a cassette cryptographer with the specified key file and
// customer nonce generator.
// Using more than one WithCipher* on the same cassette is ambiguous.
func (cb *CassetteLoader) WithCipherCustomNonce(crypterNonce CrypterNonceProvider, keyFile string, nonceGenerator encryption.NonceGenerator) *CassetteLoader {
key, err := os.ReadFile(keyFile)
if err != nil {
panic(fmt.Sprintf("%+v", err))
}
cr, err := crypterNonce(key, nonceGenerator)
if err != nil {
panic(fmt.Sprintf("%+v", err))
}
cb.opts = append(cb.opts, cassette.WithCrypter(cr))
return cb
}
// WithCassette is an optional functional parameter to provide a VCR with
// a cassette to load.
// Cassette options may be provided (e.g. cryptography).
func (cb *CassetteLoader) make() *cassette.Cassette {
if cb == nil {
panic("please select a cassette for the VCR")
}
return cassette.LoadCassette(cb.cassetteName, cb.opts...)
}
// NewVCR creates a new VCR.
func NewVCR(cassetteLoader *CassetteLoader, settings ...Setting) *ControlPanel {
var vcrSettings VCRSettings
vcrSettings.cassette = cassetteLoader.make()
for _, option := range settings {
option(&vcrSettings)
}
// use a default client if none provided
if vcrSettings.client == nil {
vcrSettings.client = http.DefaultClient
}
// use a default vcrTransport if none provided
if vcrSettings.client.Transport == nil {
vcrSettings.client.Transport = http.DefaultTransport
}
// use a default RequestMatcher if none provided
if vcrSettings.requestMatcher == nil {
vcrSettings.requestMatcher = NewStrictRequestMatcher()
}
// create VCR's HTTP client
vcrClient := &http.Client{
Transport: &vcrTransport{
pcb: &PrintedCircuitBoard{
requestMatcher: vcrSettings.requestMatcher,
trackRecordingMutators: vcrSettings.trackRecordingMutators,
trackReplayingMutators: vcrSettings.trackReplayingMutators,
httpMode: vcrSettings.httpMode,
readOnly: vcrSettings.readOnly,
},
cassette: vcrSettings.cassette,
transport: vcrSettings.client.Transport,
},
// copy the attributes of the original http.Client
CheckRedirect: vcrSettings.client.CheckRedirect,
Jar: vcrSettings.client.Jar,
Timeout: vcrSettings.client.Timeout,
}
// return
return &ControlPanel{
client: vcrClient,
}
}