httplog

package
v0.5.0-beta.2 Latest Latest
Warning

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

Go to latest
Published: Sep 25, 2026 License: PostgreSQL Imports: 10 Imported by: 0

Documentation

Overview

Package httplog renders HTTP requests and responses to a diagnostic stream at an ordered level, and is the one place in this CLI that decides what must never be printed. It is shared rather than copied per module because a masking fix landed in one copy and not another leaks credentials unnoticed.

Index

Constants

View Source
const MaxDumpBytes = 8192

MaxDumpBytes bounds each dumped body; truncate counts it in characters. 8 KB rather than the 512 internal/starfleet/conn uses for one-line error excerpts, which would clip the payload --debug is enabled to read. Unbounded once landed a 200 KB proxy error page whole on stderr.

Variables

This section is empty.

Functions

func HeaderLines

func HeaderLines(h http.Header) []string

HeaderLines renders h as "Name: value" lines in sorted order, with the values of maskedHeaders replaced by the mask. Callers add their own prefix.

Exported so the dry-run report masks headers through the same rule; maskedHeaders has no other consumer. Sorted so two runs diff cleanly.

func RedactBody

func RedactBody(raw []byte, limit int) string

RedactBody renders a body for a diagnostic stream: bounded at limit characters, with the VALUE of every credential-bearing field masked and everything else passed through byte for byte.

It does not decode and re-encode, because that erases the difference between an explicit `"plan_expires_at": null` and an omitted key, which a typed parser already collapses and the wire dump exists to reveal. The decoder only LOCATES each secret value's byte span.

Masking per value rather than replacing the body keeps --debug useful: a service write reduced to its top-level keys is the single key "services", while per-value masking keeps allow_writes, embedding_model and the service id readable.

Secret fields are masked at any depth, so a wrapper object cannot smuggle a token past, and a composite value (byoc's `credentials`) is masked whole. It fails CLOSED: if the spans cannot be computed, the whole body is replaced. HTML does not parse as JSON, so a proxy or SSO interstitial passes through untouched.

func Wrap

func Wrap(base http.RoundTripper, out io.Writer,
	lvl Level) http.RoundTripper

Wrap returns base wrapped so that traffic through it is rendered to out at lvl. At Off, or with no writer, it returns base itself: the quiet path is every normal command, and gets no extra layer.

Types

type Level

type Level int

Level is how much of an exchange reaches the diagnostic stream. The values are ordered, so callers compare rather than enumerate.

const (
	// Off prints nothing.
	Off Level = iota
	// Verbose prints the request line, a masked Authorization header
	// when one is present, and the response status with elapsed time.
	// No bodies: they would bury the progress it exists to show.
	Verbose
	// Debug prints everything Verbose does, plus every request and
	// response header and both bodies.
	Debug
)

func LevelFor

func LevelFor(verbose, debug bool) Level

LevelFor maps the two global flags onto a level. --debug implies --verbose; that is the documented contract, and this is where it is defined.

func (Level) String

func (l Level) String() string

String names the level for diagnostics and test output.

type Transport

type Transport struct {
	Base  http.RoundTripper
	Out   io.Writer
	Level Level
}

Transport renders each exchange to Out. Use Wrap, so the Off case stays uniform.

func (*Transport) RoundTrip

func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip renders req, delegates to Base, and renders the response. It never fails a request for a diagnostic reason.

Jump to

Keyboard shortcuts

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