re

package module
v0.3.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 5, 2025 License: Apache-2.0 Imports: 4 Imported by: 10

README

re 🔖

GoDoc Version Build Status Go Report Card Codecov

In some circumstances, it's necessary to us a Golang io.Reader multiple times. While readers themselves don't support this, we can fake it by copying the value into a buffer and then replaying the values whenever asked.

WARNING: This library uses more resources than a regular reader. In particular, it's a bad idea to use this for very large values (because it keeps the whole dataset in memory) or long running streaming readers (because it reads and replays the entire value). It should only be used when the data is small and you reasonably believe you will need to use the reader a second time.

However, it is useful for processing HTTP requests, particularly when multiple layers of an app all need the same access to the HTTP request body. This happens, for example, when an http signature middleware needs to validate the body digest before allowing the transaction to pass through to the main handler app.

Read from an io.Reader Multiple Times

To use this library, just wrap any reader in a re.Reader. This will copy all of its values into a memory buffer which can be re-read as many times as necessary.

func main() {
	// First, a single-use reader 
	singleReader := strings.NewReader(("Hello World."))

	// This reader will work multiple times
	multipleReader := re.NewReader(singleReader)

    readAndPrint(multipleReader)
    readAndPrint(multipleReader)
    readAndPrint(multipleReader)
}

func readAndPrint(r io.Reader) {
    b, _ := io.ReadAll(r)
    fmt.Println(string(b))
}
	

Read the Body from an http.Request or http.Response

This library also includes helper functions to read from http.Request and http.Response bodies. These functions do not use a re.Reader, but simply read the existing Body reader then replace it with a fresh reader that can be read again by another process.

func handler(request *http.Request) {
	body, err := re.ReadRequestBody(request)
}

Issues and Pull Requests Welcome

As is everything in life, re is a work in progress and will benefit from your experience reports, use cases, and contributions. If you have an idea for making this library better, send in a pull request. We're all in this together! 🔖

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CloneResponse added in v0.3.0

func CloneResponse(original *http.Response) http.Response

CloneResponse makes an exact copy of a response WITHOUT closing the original response body.

func ReadRequestBody added in v0.2.0

func ReadRequestBody(request *http.Request) ([]byte, error)

ReadRequestBody reads the response.Body then replaces it with a new reader that can be read again by another process

func ReadResponseBody added in v0.2.0

func ReadResponseBody(response *http.Response) ([]byte, error)

ReadResponseBody reads the response.Body then replaces it with a new reader that can be read again by another process

This is inspired by several articles, including: https://blog.manugarri.com/how-to-reuse-http-response-body-in-golang-2/ https://medium.com/@xoen/golang-read-from-an-io-readwriter-without-loosing-its-content-2c6911805361

Types

type Reader

type Reader struct {
	// contains filtered or unexported fields
}

Reader is a simple re-usable io.Reader. It stores the entire contents of another io.Reader in memory, so it should not be used with large files.

It implements the io.ReadCloser interface, along with a few other convenience methods.

This is inspired by several articles, including: https://blog.flexicondev.com/read-go-http-request-body-multiple-times

func NewReader

func NewReader(input io.Reader) (Reader, error)

NewReader creates a new Reader from the given io.Reader

func NewReaderFromBytes

func NewReaderFromBytes(bytes []byte) Reader

NewReaderFromBytes creates a new Reader from the given slice of bytes

func (Reader) Bytes

func (r Reader) Bytes() []byte

Bytes returns the Reader's contents as a slice of bytes

func (Reader) Close

func (r Reader) Close() error

Close implements the io.Closer interface

func (Reader) Read

func (r Reader) Read(p []byte) (int, error)

Read implements the io.Reader interface

func (Reader) String

func (r Reader) String() string

String returns the Reader's contents as a string.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL