diff --git a/README.md b/README.md index 4032cb4..cd1843c 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,6 @@ [![Go Report Card](https://goreportcard.com/badge/github.com/dnaeon/go-vcr)](https://goreportcard.com/report/github.com/dnaeon/go-vcr) [![codecov](https://codecov.io/gh/dnaeon/go-vcr/branch/master/graph/badge.svg)](https://codecov.io/gh/dnaeon/go-vcr) - `go-vcr` simplifies testing by recording your HTTP interactions and replaying them in future runs in order to provide fast, deterministic and accurate testing of your code. @@ -76,6 +75,7 @@ func main() { ``` ## Custom Request Matching + During replay mode, You can customize the way incoming requests are matched against the recorded request/response pairs by defining a Matcher function. For example, the following matcher will match on @@ -125,6 +125,25 @@ r.AddFilter(func(i *cassette.Interaction) error { }) ``` +## Passing Through Requests + +Sometimes you want to allow specific requests to pass through to the remote +server without recording anything. + +Globally, you can use `ModeDisabled` for this, but if you want to disable the +recorder for individual requests, you can add `Passthrough` functions to the +recorder. The function takes a pointer to the original request, and returns a +boolean, indicating if the request should pass through to the remote server. + +Here's an example to pass through requests to a specific endpoint: + +```go +// Pass through the request to the remote server if the path matches "/login". +r.AddPassthrough(func(req *http.Request) bool { + return req.URL.Path == "/login" +}) +``` + ## License `go-vcr` is Open Source and licensed under the diff --git a/recorder/recorder.go b/recorder/recorder.go index 2477d1e..750aecd 100644 --- a/recorder/recorder.go +++ b/recorder/recorder.go @@ -61,8 +61,14 @@ type Recorder struct { // realTransport is the underlying http.RoundTripper to make real requests realTransport http.RoundTripper + + // Pass through requests. + Passthroughs []Passthrough } +// Passthrough function allows ignoring certain requests. +type Passthrough func(*http.Request) bool + // SetTransport can be used to configure the behavior of the 'real' client used in record-mode func (r *Recorder) SetTransport(t http.RoundTripper) { r.realTransport = t @@ -198,6 +204,12 @@ func (r *Recorder) RoundTrip(req *http.Request) (*http.Response, error) { if r.mode == ModeDisabled { return r.realTransport.RoundTrip(req) } + for _, passthrough := range r.Passthroughs { + if passthrough(req) { + return r.realTransport.RoundTrip(req) + } + } + // Pass cassette and mode to handler, so that interactions can be // retrieved or recorded depending on the current recorder mode interaction, err := requestHandler(req, r.cassette, r.mode, r.realTransport) @@ -265,6 +277,12 @@ func (r *Recorder) SetMatcher(matcher cassette.Matcher) { } } +// AddPassthrough appends a hook to determine if a request should be ignored by the +// recorder. +func (r *Recorder) AddPassthrough(pass Passthrough) { + r.Passthroughs = append(r.Passthroughs, pass) +} + // AddFilter appends a hook to modify a request before it is recorded. // // Filters are useful for filtering out sensitive parameters from the recorded data.