body

package
v0.28.0 Latest Latest
Warning

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

Go to latest
Published: Aug 25, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package body contains the request-body and response-stream primitives used by the fetch request pipeline.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNotReplayable is returned when an operation needs a second request
	// stream but the original source can only be consumed once.
	ErrNotReplayable = errors.New("request body is not replayable")
	// ErrBodyAlreadyOpen is returned when a one-shot body has already been
	// handed to a caller and another independent stream is requested.
	ErrBodyAlreadyOpen = errors.New("request body has already been opened")
)

Functions

func Attach

func Attach(req *http.Request, b *Body)

Attach installs b as req.Body, sets known length/GetBody, and preserves the source in the request context.

func WithSource

func WithSource(ctx context.Context, b *Body) context.Context

WithSource associates a request with its body source for dry-run and lifecycle-aware consumers.

Types

type Body

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

Body describes one request-body source. A Body is lazy: constructing it does not read stdin, open a file stream, or consume a generated body. The first Read opens the source, while Replay opens a fresh stream when the source is replayable.

func NewBytes

func NewBytes(data []byte, contentType string) *Body

NewBytes creates a replayable in-memory body.

func NewFactory

func NewFactory(open func() (io.ReadCloser, error), length int64, contentType string, replayable bool) *Body

NewFactory creates a body from a stream factory. length must be -1 when unknown. A replayable factory must return an independent stream each time.

func NewFile

func NewFile(path, contentType string) (*Body, error)

NewFile creates a replayable, exact-length body for a regular file. Each open verifies that the path still names the same regular file and has not changed size since argument parsing.

func NewFileFromOpenFile

func NewFileFromOpenFile(f *os.File, contentType string) (body *Body, err error)

NewFileFromOpenFile converts an already-open regular file into a replayable source and closes the caller's descriptor. It is useful at the boundary where CLI parsing has already opened a file to inspect its content type.

func NewReader

func NewReader(r io.Reader, length int64, contentType string) *Body

NewReader creates a one-shot body from r.

func NewReaderAt

func NewReaderAt(r io.ReaderAt, offset, length int64, contentType string) *Body

NewReaderAt creates independent replay streams over a random-access source.

func NewSeekable

func NewSeekable(r io.ReadSeeker, offset, length int64, contentType string) *Body

NewSeekable creates a one-shot body over a seekable reader. A general ReadSeeker shares one mutable cursor, so it cannot safely provide concurrent independent replay streams.

func SourceFromContext

func SourceFromContext(ctx context.Context) (*Body, bool)

SourceFromContext returns the source attached by WithSource.

func (*Body) Close

func (b *Body) Close() error

Close closes the active first stream. Replay streams returned by Replay or Open are owned by their caller and are not affected by this method.

func (*Body) ContentLength

func (b *Body) ContentLength() int64

ContentLength reports the known body length, or -1 when unknown.

func (*Body) ContentType

func (b *Body) ContentType() string

ContentType reports the source's declared content type, if any.

func (*Body) Materialize

func (b *Body) Materialize(max int64) ([]byte, error)

Materialize consumes the body with a hard cap and turns it into a replayable in-memory body. It is for protocol conversions and signing, not ordinary uploads.

func (*Body) Open

func (b *Body) Open() (io.ReadCloser, error)

Open returns the body's first stream. Replayable sources may also be opened repeatedly; one-shot sources return ErrBodyAlreadyOpen after the first stream has been handed out.

func (*Body) Preview

func (b *Body) Preview(max int64) (Preview, error)

Preview reads at most max+1 bytes without consuming the stream that Read will use. For one-shot sources the unopened stream is retained and later Read returns the complete body, including the previewed prefix.

func (*Body) Read

func (b *Body) Read(p []byte) (int, error)

Read lazily opens the first stream, making Body safe to use directly as an http.Request.Body without eagerly consuming stdin or files.

func (*Body) Replay

func (b *Body) Replay() (io.ReadCloser, error)

Replay opens an independent stream. It never consumes the body's first stream and is intended for http.Request.GetBody and retry/authentication.

func (*Body) Replayable

func (b *Body) Replayable() bool

Replayable reports whether independent streams can be opened.

func (*Body) SetCleanup

func (b *Body) SetCleanup(cleanup func() error)

SetCleanup registers a callback run once when the body is closed. It is intended for sources with resources that are not owned by an individual stream, such as a temporary spool file.

type Preview

type Preview struct {
	Data      []byte
	Truncated bool
}

Preview is a bounded, non-destructive view of a body. Data may contain at most Limit bytes. Truncated is true when at least one further byte exists.

type Stream

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

Stream is a single-read response pipeline. Tee writers observe the bytes as they pass through; consumers never need to reread the response body. AddTee must be called before concurrent reads begin.

func NewStream

func NewStream(source io.ReadCloser) *Stream

func (*Stream) AddTee

func (s *Stream) AddTee(w io.Writer)

AddTee adds a synchronous observer. A writer error is returned to the consumer, while the source remains closed by Stream.Close.

func (*Stream) Close

func (s *Stream) Close() error

func (*Stream) ProgressBytes

func (s *Stream) ProgressBytes() (int64, bool)

ProgressBytes forwards an optional byte counter from the source. Decoding response bodies can expose wire-byte progress even though Stream returns decoded bytes to its consumer.

func (*Stream) Read

func (s *Stream) Read(p []byte) (int, error)

Jump to

Keyboard shortcuts

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