rr.go

Overview

The rr.go file implements the httprr package, which provides HTTP request recording and replaying capabilities primarily aimed at testing scenarios. It defines a mechanism to capture HTTP request-response pairs during a test run ("record" mode) and to serve those previously recorded responses later without making real network calls ("replay" mode). This approach allows deterministic, repeatable tests that depend on HTTP interactions.

The package's main type is RecordReplay, an implementation of the http.RoundTripper interface. Depending on a command-line flag (-httprecord), RecordReplay either records live HTTP traffic to a file or reads from a previously recorded file to replay responses. The recorded data is stored in a custom plain-text trace format.

Key Components and Their Functionality

Global Variables and Initialization

RecordReplay Type

RecordReplay is the core type that implements HTTP recording and replaying:

type RecordReplay struct {
	file string            // Path to the trace file
	real http.RoundTripper // Actual RoundTripper used for real HTTP calls

	mu        sync.Mutex
	reqScrub  []func(*http.Request) error  // Request scrubbers to canonicalize requests
	respScrub []func(*bytes.Buffer) error  // Response scrubbers to canonicalize responses
	replay    map[string]string            // Replay map: request key → response log entry
	record    *os.File                     // File handle for recording mode
	writeErr  error                        // Error encountered during writing
}

Methods on RecordReplay

ScrubReq

func (rr *RecordReplay) ScrubReq(scrubs ...func(req *http.Request) error)

Adds request scrubbing functions that preprocess requests before they are logged or used as replay keys. Useful for removing secrets or normalizing non-deterministic fields.

ScrubResp

func (rr *RecordReplay) ScrubResp(scrubs ...func(*bytes.Buffer) error)

Adds response scrubbing functions that preprocess the raw byte representation of HTTP responses before logging or replaying.

Recording

func (rr *RecordReplay) Recording() bool

Returns true if the RecordReplay is in recording mode (i.e., writing to a trace file).

Open

func Open(file string, rt http.RoundTripper) (*RecordReplay, error)

Creates a new RecordReplay instance either in record or replay mode depending on the -httprecord flag and the file name.

Recording (Package-level)

func Recording(file string) (bool, error)

Returns whether recording mode is enabled for the given file by matching -httprecord against the file name regex.

create (private)

func create(file string, rt http.RoundTripper) (*RecordReplay, error)

Creates a new file for recording, writes a header, and returns a recording RecordReplay.

open (private)

func open(file string, rt http.RoundTripper) (*RecordReplay, error)

Loads a previously recorded trace file and parses it into an in-memory map for replay.

Client

func (rr *RecordReplay) Client() *http.Client

Returns an http.Client configured to use this RecordReplay instance as its Transport.

RoundTrip

func (rr *RecordReplay) RoundTrip(req *http.Request) (*http.Response, error)

Implements the http.RoundTripper interface.

The method uses reqWire and respWire helpers to serialize requests and responses into canonical wire formats suitable for logging and lookup.

reqWire (private)

func (rr *RecordReplay) reqWire(req *http.Request) (string, error)

Serializes a request into a canonical string key for logging or lookup.

respWire (private)

func (rr *RecordReplay) respWire(resp *http.Response) (string, error)

Serializes a response into a canonical byte-string for logging.

replayRoundTrip (private)

func (rr *RecordReplay) replayRoundTrip(req *http.Request, reqLog string) (*http.Response, error)

Given a serialized request key, looks up the cached response in replay and returns it as an *http.Response.

Returns an error if the request is not found or the response log is corrupt.

writeError (private)

func (rr *RecordReplay) writeError() error

Returns any existing error encountered during writing to the recording file.

writeLog (private)

func (rr *RecordReplay) writeLog(reqWire, respWire string) error

Appends a new request-response record to the recording log file.

Close

func (rr *RecordReplay) Close() error

Closes the RecordReplay.

Body Type

type Body struct {
	Data       []byte
	ReadOffset int
}

Custom implementation of io.ReadCloser for request bodies in scrubbers.

Implementation Details and Algorithms

Interaction with Other Parts of the System

Visual Diagram

classDiagram
class RecordReplay {
-file: string
-real: http.RoundTripper
-mu: sync.Mutex
-reqScrub: []func(*http.Request) error
-respScrub: []func(*bytes.Buffer) error
-replay: map[string]string
-record: *os.File
-writeErr: error
+ScrubReq(...)
+ScrubResp(...)
+Recording() bool
+Open(file, rt) *RecordReplay
+Client() *http.Client
+RoundTrip(req *http.Request) *http.Response
+Close()
}
class Body {
-Data: []byte
-ReadOffset: int
+Read(p []byte) (int, error)
+Close() error
}
RecordReplay --> http.RoundTripper : implements
RecordReplay o-- Body : uses for req.Body