diff --git a/httprr/rr.go b/httprr/rr.go
new file mode 100644
index 0000000..6acde80
--- /dev/null
+++ b/httprr/rr.go
@@ -0,0 +1,394 @@
+// Copyright 2024 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package httprr implements HTTP record and replay, mainly for use in tests.
+//
+// [Open] creates a new [RecordReplay]. Whether it is recording or replaying
+// is controlled by the -httprecord flag, which is defined by this package
+// only in test programs (built by “go test”).
+// See the [Open] documentation for more details.
+package httprr
+
+import (
+	"bufio"
+	"bytes"
+	"cmp"
+	"context"
+	"flag"
+	"fmt"
+	"io"
+	"net/http"
+	"os"
+	"regexp"
+	"strconv"
+	"strings"
+	"sync"
+	"testing"
+)
+
+var record = new(string)
+
+func init() {
+	if testing.Testing() {
+		record = flag.String("httprecord", "", "re-record traces for files matching `regexp`")
+	}
+}
+
+// A RecordReplay is an [http.RoundTripper] that can operate in two modes: record and replay.
+//
+// In record mode, the RecordReplay invokes another RoundTripper
+// and logs the (request, response) pairs to a file.
+//
+// In replay mode, the RecordReplay responds to requests by finding
+// an identical request in the log and sending the logged response.
+type RecordReplay struct {
+	file string            // file being read or written
+	real http.RoundTripper // real HTTP connection
+
+	mu        sync.Mutex
+	reqScrub  []func(*http.Request) error // scrubbers for logging requests
+	respScrub []func(*bytes.Buffer) error // scrubbers for logging responses
+	replay    map[string]string           // if replaying, the log
+	record    *os.File                    // if recording, the file being written
+	writeErr  error                       // if recording, any write error encountered
+}
+
+// ScrubReq adds new request scrubbing functions to rr.
+//
+// Before using a request as a lookup key or saving it in the record/replay log,
+// the RecordReplay calls each scrub function, in the order they were registered,
+// to canonicalize non-deterministic parts of the request and remove secrets.
+// Scrubbing only applies to a copy of the request used in the record/replay log;
+// the unmodified original request is sent to the actual server in recording mode.
+// A scrub function can assume that if req.Body is not nil, then it has type [*Body].
+//
+// Calling ScrubReq adds to the list of registered request scrubbing functions;
+// it does not replace those registered by earlier calls.
+func (rr *RecordReplay) ScrubReq(scrubs ...func(req *http.Request) error) {
+	rr.reqScrub = append(rr.reqScrub, scrubs...)
+}
+
+// ScrubResp adds new response scrubbing functions to rr.
+//
+// Before using a response as a lookup key or saving it in the record/replay log,
+// the RecordReplay calls each scrub function on a byte representation of the
+// response, in the order they were registered, to canonicalize non-deterministic
+// parts of the response and remove secrets.
+//
+// Calling ScrubResp adds to the list of registered response scrubbing functions;
+// it does not replace those registered by earlier calls.
+//
+// Clients should be careful when loading the bytes into [*http.Response] using
+// [http.ReadResponse]. This function can set [http.Response].Close to true even
+// when the original response had it false. See code in go/src/net/http.Response.Write
+// and go/src/net/http.Write for more info.
+func (rr *RecordReplay) ScrubResp(scrubs ...func(*bytes.Buffer) error) {
+	rr.respScrub = append(rr.respScrub, scrubs...)
+}
+
+// Recording reports whether the rr is in recording mode.
+func (rr *RecordReplay) Recording() bool {
+	return rr.record != nil
+}
+
+// Open opens a new record/replay log in the named file and
+// returns a [RecordReplay] backed by that file.
+//
+// By default Open expects the file to exist and contain a
+// previously-recorded log of (request, response) pairs,
+// which [RecordReplay.RoundTrip] consults to prepare its responses.
+//
+// If the command-line flag -httprecord is set to a non-empty
+// regular expression that matches file, then Open creates
+// the file as a new log. In that mode, [RecordReplay.RoundTrip]
+// makes actual HTTP requests using rt but then logs the requests and
+// responses to the file for replaying in a future run.
+func Open(file string, rt http.RoundTripper) (*RecordReplay, error) {
+	record, err := Recording(file)
+	if err != nil {
+		return nil, err
+	}
+	if record {
+		return create(file, rt)
+	}
+	return open(file, rt)
+}
+
+// OpenForRecording opens the file for recording.
+func OpenForRecording(file string, rt http.RoundTripper) (*RecordReplay, error) {
+	return create(file, rt)
+}
+
+// Recording reports whether the "-httprecord" flag is set
+// for the given file.
+// It return an error if the flag is set to an invalid value.
+func Recording(file string) (bool, error) {
+	if *record != "" {
+		re, err := regexp.Compile(*record)
+		if err != nil {
+			return false, fmt.Errorf("invalid -httprecord flag: %v", err)
+		}
+		if re.MatchString(file) {
+			return true, nil
+		}
+	}
+	return false, nil
+}
+
+// creates creates a new record-mode RecordReplay in the file.
+func create(file string, rt http.RoundTripper) (*RecordReplay, error) {
+	f, err := os.Create(file)
+	if err != nil {
+		return nil, err
+	}
+
+	// Write header line.
+	// Each round-trip will write a new request-response record.
+	if _, err := fmt.Fprintf(f, "httprr trace v1\n"); err != nil {
+		// unreachable unless write error immediately after os.Create
+		f.Close()
+		return nil, err
+	}
+	rr := &RecordReplay{
+		file:   file,
+		real:   rt,
+		record: f,
+	}
+	return rr, nil
+}
+
+// open opens a replay-mode RecordReplay using the data in the file.
+func open(file string, rt http.RoundTripper) (*RecordReplay, error) {
+	// Note: To handle larger traces without storing entirely in memory,
+	// could instead read the file incrementally, storing a map[hash]offsets
+	// and then reread the relevant part of the file during RoundTrip.
+	bdata, err := os.ReadFile(file)
+	if err != nil {
+		return nil, err
+	}
+
+	// Trace begins with header line.
+	data := string(bdata)
+	line, data, ok := strings.Cut(data, "\n")
+	if !ok || line != "httprr trace v1" {
+		return nil, fmt.Errorf("read %s: not an httprr trace", file)
+	}
+
+	replay := make(map[string]string)
+	for data != "" {
+		// Each record starts with a line of the form "n1 n2\n"
+		// followed by n1 bytes of request encoding and
+		// n2 bytes of response encoding.
+		line, data, ok = strings.Cut(data, "\n")
+		f1, f2, _ := strings.Cut(line, " ")
+		n1, err1 := strconv.Atoi(f1)
+		n2, err2 := strconv.Atoi(f2)
+		if !ok || err1 != nil || err2 != nil || n1 > len(data) || n2 > len(data[n1:]) {
+			return nil, fmt.Errorf("read %s: corrupt httprr trace", file)
+		}
+		var req, resp string
+		req, resp, data = data[:n1], data[n1:n1+n2], data[n1+n2:]
+		replay[req] = resp
+	}
+
+	rr := &RecordReplay{
+		file:   file,
+		real:   rt,
+		replay: replay,
+	}
+	return rr, nil
+}
+
+// Client returns an http.Client using rr as its transport.
+// It is a shorthand for:
+//
+//	return &http.Client{Transport: rr}
+//
+// For more complicated uses, use rr or the [RecordReplay.RoundTrip] method directly.
+func (rr *RecordReplay) Client() *http.Client {
+	return &http.Client{Transport: rr}
+}
+
+// A Body is an io.ReadCloser used as an HTTP request body.
+// In a Scrubber, if req.Body != nil, then req.Body is guaranteed
+// to have type *Body, making it easy to access the body to change it.
+type Body struct {
+	Data       []byte
+	ReadOffset int
+}
+
+// Read reads from the body, implementing io.Reader.
+func (b *Body) Read(p []byte) (int, error) {
+	n := copy(p, b.Data[b.ReadOffset:])
+	if n == 0 {
+		return 0, io.EOF
+	}
+	b.ReadOffset += n
+	return n, nil
+}
+
+// Close is a no-op, implementing io.Closer.
+func (b *Body) Close() error {
+	return nil
+}
+
+// RoundTrip implements [http.RoundTripper].
+//
+// If rr has been opened in record mode, RoundTrip passes the requests on to
+// the RoundTripper specified in the call to [Open] and then logs the
+// (request, response) pair to the underlying file.
+//
+// If rr has been opened in replay mode, RoundTrip looks up the request in the log
+// and then responds with the previously logged response.
+// If the log does not contain req, RoundTrip returns an error.
+func (rr *RecordReplay) RoundTrip(req *http.Request) (*http.Response, error) {
+	reqWire, err := rr.reqWire(req)
+	if err != nil {
+		return nil, err
+	}
+
+	// If we're in replay mode, replay a response.
+	if rr.replay != nil {
+		return rr.replayRoundTrip(req, reqWire)
+	}
+
+	// Otherwise run a real round trip and save the request-response pair.
+	// But if we've had a log write error already, don't bother.
+	if err := rr.writeError(); err != nil {
+		return nil, err
+	}
+	resp, err := rr.real.RoundTrip(req)
+	if err != nil {
+		return nil, err
+	}
+
+	// Encode resp and decode to get a copy for our caller.
+	respWire, err := rr.respWire(resp)
+	if err != nil {
+		return nil, err
+	}
+	if err := rr.writeLog(reqWire, respWire); err != nil {
+		return nil, err
+	}
+	return resp, nil
+}
+
+// reqWire returns the wire-format HTTP request key to be
+// used for request when saving to the log or looking up in a
+// previously written log. It consumes the original req.Body
+// but modifies req.Body to be an equivalent [*Body].
+func (rr *RecordReplay) reqWire(req *http.Request) (string, error) {
+	// rkey is the scrubbed request used as a lookup key.
+	// Clone req including req.Body.
+	rkey := req.Clone(context.Background())
+	if req.Body != nil {
+		body, err := io.ReadAll(req.Body)
+		req.Body.Close()
+		if err != nil {
+			return "", err
+		}
+		req.Body = &Body{Data: body}
+		rkey.Body = &Body{Data: bytes.Clone(body)}
+	}
+
+	// Canonicalize and scrub request key.
+	for _, scrub := range rr.reqScrub {
+		if err := scrub(rkey); err != nil {
+			return "", err
+		}
+	}
+
+	// Now that scrubbers are done potentially modifying body, set length.
+	if rkey.Body != nil {
+		rkey.ContentLength = int64(len(rkey.Body.(*Body).Data))
+	}
+
+	// Serialize rkey to produce the log entry.
+	// Use WriteProxy instead of Write to preserve the URL's scheme.
+	var key strings.Builder
+	if err := rkey.WriteProxy(&key); err != nil {
+		return "", err
+	}
+	return key.String(), nil
+}
+
+// respWire returns the wire-format HTTP response log entry.
+// It modifies resp but leaves an equivalent response in its place.
+func (rr *RecordReplay) respWire(resp *http.Response) (string, error) {
+	var key bytes.Buffer
+	if err := resp.Write(&key); err != nil {
+		return "", err
+	}
+	resp2, err := http.ReadResponse(bufio.NewReader(bytes.NewReader(key.Bytes())), resp.Request)
+	if err != nil {
+		// unreachable unless resp.Write does not round-trip with http.ReadResponse
+		return "", err
+	}
+	*resp = *resp2
+
+	for _, scrub := range rr.respScrub {
+		if err := scrub(&key); err != nil {
+			return "", err
+		}
+	}
+	return key.String(), nil
+}
+
+// replayRoundTrip implements RoundTrip using the replay log.
+func (rr *RecordReplay) replayRoundTrip(req *http.Request, reqLog string) (*http.Response, error) {
+	respLog, ok := rr.replay[reqLog]
+	if !ok {
+		return nil, fmt.Errorf("cached HTTP response not found for:\n%s", reqLog)
+	}
+	resp, err := http.ReadResponse(bufio.NewReader(strings.NewReader(respLog)), req)
+	if err != nil {
+		return nil, fmt.Errorf("read %s: corrupt httprr trace: %v", rr.file, err)
+	}
+	return resp, nil
+}
+
+// writeError reports any previous log write error.
+func (rr *RecordReplay) writeError() error {
+	rr.mu.Lock()
+	defer rr.mu.Unlock()
+	return rr.writeErr
+}
+
+// writeLog writes the request-response pair to the log.
+// If a write fails, writeLog arranges for rr.broken to return
+// an error and deletes the underlying log.
+func (rr *RecordReplay) writeLog(reqWire, respWire string) error {
+	rr.mu.Lock()
+	defer rr.mu.Unlock()
+
+	if rr.writeErr != nil {
+		// Unreachable unless concurrent I/O error.
+		// Caller should have checked already.
+		return rr.writeErr
+	}
+
+	_, err1 := fmt.Fprintf(rr.record, "%d %d\n", len(reqWire), len(respWire))
+	_, err2 := rr.record.WriteString(reqWire)
+	_, err3 := rr.record.WriteString(respWire)
+	if err := cmp.Or(err1, err2, err3); err != nil {
+		rr.writeErr = err
+		rr.record.Close()
+		os.Remove(rr.file)
+		return err
+	}
+
+	return nil
+}
+
+// Close closes the RecordReplay.
+// It is a no-op in replay mode.
+func (rr *RecordReplay) Close() error {
+	if rr.writeErr != nil {
+		return rr.writeErr
+	}
+	if rr.record != nil {
+		return rr.record.Close()
+	}
+	return nil
+}
