Documentation
¶
Overview ¶
Package view renders captured HTTP bodies and headers into the compact, token-efficient text that pano shows to LLM agents and humans.
The package has four responsibilities:
- Render turns a raw wire body into one of five views (summary, schema, truncated, pretty, raw), after removing any Content-Encoding and optionally selecting a sub-value with a gjson/JSONPath expression. Binary bodies are never inlined.
- Decode strips gzip, deflate, brotli and zstd encodings with an output bound so a small compressed body cannot expand without limit.
- RedactHeaders, RedactText and Mask hide credentials (API keys, bearer tokens, cookies, JWTs, password fields, …) while keeping a short stable fingerprint so two occurrences of the same secret can still be matched.
- DiffJSON, DiffText and DiffHeaders produce short structural diffs between two bodies or header sets.
The package depends only on internal/mimeclass and third-party helpers; it must not import internal/store.
Index ¶
- Constants
- Variables
- func Decode(encoding string, b []byte, limit int64) ([]byte, error)
- func DiffHeaders(a, b http.Header, ignore []string) (string, int)
- func DiffJSON(a, b []byte, maxChanges int) (string, int)
- func DiffText(a, b string, maxLines int) (string, int)
- func FormatHeaders(h http.Header) string
- func Mask(value string) string
- func NormalizePath(p string) string
- func RedactHeaders(h http.Header, reveal bool) (http.Header, int)
- func RedactText(s string) (string, int)
- func Render(mode string, body []byte, encoding, mime, path string, opts Options) (text string, redacted int, binary bool, err error)
- type Options
Constants ¶
const ( // DefaultMaxChanges is used by DiffJSON and DiffHeaders when maxChanges // is zero or negative. DefaultMaxChanges = 50 // DefaultMaxDiffLines is used by DiffText when maxLines is zero or // negative. DefaultMaxDiffLines = 200 )
Diff limits.
const ( ViewSummary = "summary" ViewSchema = "schema" ViewTruncated = "truncated" ViewPretty = "pretty" ViewRaw = "raw" )
View modes accepted by Render.
const ( // DefaultMaxBytes is the body budget used when Options.MaxBytes is zero. DefaultMaxBytes = 4096 // MaxBytesCap is the hard upper bound on Options.MaxBytes (1 MiB). MaxBytesCap = 1 << 20 // DefaultStringTruncate is the string length above which summary and // schema views elide string values. DefaultStringTruncate = 200 // DefaultArraySample is the number of array elements a summary inspects. DefaultArraySample = 3 // DefaultDecodeLimit bounds the decoded size of an encoded body (8 MiB). DefaultDecodeLimit = 8 << 20 )
Defaults and hard limits applied to Options and to the renderers.
const BinaryNote = "(binary; use pano export har or `pano show --out FILE` to save)"
BinaryNote is the content line Render emits instead of a binary body.
Variables ¶
var ErrDecodeLimit = errors.New("decoded body exceeds limit")
ErrDecodeLimit is returned (wrapped) by Decode when the decoded output would exceed the requested limit. The output produced up to the limit is returned alongside the error.
var Extra struct { Headers []string Patterns []*regexp.Regexp }
Extra holds user-configured additions to the built-in redaction rules. Headers are extra header names to mask (case-insensitive) and Patterns are extra regular expressions whose whole match is masked by RedactText. Set it once at start-up, before any concurrent use of this package.
Functions ¶
func Decode ¶
Decode removes a Content-Encoding from b. Supported codings are gzip, x-gzip, deflate (zlib-wrapped or raw), br and zstd; comma-chained values such as "gzip, br" are applied in reverse order. Output is bounded by limit bytes (0 means DefaultDecodeLimit). The input is returned unchanged when encoding is "" or "identity".
On a truncated or corrupt stream Decode returns whatever it managed to decode together with a non-nil error, so callers can still show partial content from bodies that were cut at capture time.
func DiffHeaders ¶
DiffHeaders compares two header sets and lists added ("+ Name: value"), removed ("- Name: value") and changed ("~ Name: old → new") headers, sorted by name. Names listed in ignore are skipped; when ignore is nil a default set of volatile headers (Date, Age, ETag, X-Request-Id, CF-Ray, Set-Cookie, Content-Length, Traceparent, X-Amzn-Trace-Id, X-Amz-Request-Id) is used. Pass an empty, non-nil slice to compare all headers. Values are compared as given, so pass RedactHeaders output when the result will be shown.
func DiffJSON ¶
DiffJSON compares two JSON documents structurally and lists the changes as "+ path: value" (added in b), "- path: value" (removed from b) and "~ path: old → new" lines, using gjson-style paths ("$" for the root). Arrays are compared positionally, with a note when their lengths differ. Values are cut at 120 characters. At most maxChanges lines are listed (default 50) followed by "… and N more"; the returned count is the total number of changes. If either input is not valid JSON it falls back to DiffText.
func DiffText ¶
DiffText compares two texts line by line and renders a unified-style diff with two lines of context per hunk. It returns the text and the number of changed (+/-) lines; at most maxLines diff lines are rendered (default 200) followed by "… and N more lines".
func FormatHeaders ¶
FormatHeaders renders headers as "Name: value" lines, one per value, sorted by name (case-insensitively).
func Mask ¶
Mask replaces a secret with a short, stable placeholder: a recognisable prefix (when the value has one), the last four characters, and the first four hex digits of the value's SHA-256, e.g. "sk-ant-…a1b2 hash:9f3c". Short values keep no prefix or suffix so nothing meaningful leaks.
func NormalizePath ¶
NormalizePath converts a JSONPath expression such as "$.a[0].b" or "$['a b'][*].c" into gjson syntax ("a.0.b", "a b.#.c"). Paths that are already gjson syntax are returned unchanged apart from trimming.
func RedactHeaders ¶
RedactHeaders returns a clone of h with credential-bearing values masked and the number of values changed. Authorization keeps its scheme, cookies keep their names and Set-Cookie keeps its attributes, so the shape of the header stays readable. Values of other headers are passed through RedactText. When reveal is true the clone is returned untouched.
func RedactText ¶
RedactText masks credentials found anywhere in s: bearer tokens, common API-key shapes (OpenAI, Anthropic, AWS, Google, GitHub, Slack, Mailgun), JWTs, basic-auth userinfo in URLs, JSON and form fields named like secrets, and any Extra.Patterns. It returns the masked text and the number of replacements. Running it over its own output changes nothing.
func Render ¶
func Render(mode string, body []byte, encoding, mime, path string, opts Options) (text string, redacted int, binary bool, err error)
Render renders a captured body in the given view mode and returns the text to show, the number of redactions applied and whether the body was treated as binary.
body holds the raw wire bytes; encoding is the Content-Encoding header (possibly comma-chained) and mime the Content-Type. path is an optional gjson path; JSONPath syntax ("$.a[0].b") is accepted and normalised with NormalizePath. The selected value is rendered with the mode, except that a plain string is shown as-is.
Every result starts with a header line such as
body: application/json 5120B [gzip→18342B] sha256:1f2e3d4c [truncated to 4096 of 18342]
followed by a newline and the content. Bodies whose MIME class is img/font/media/bin, or that are not valid UTF-8 after decoding, are never inlined: the content is BinaryNote and binary is true.
Modes: ViewSummary (content-type aware digest), ViewSchema (inferred shape of JSON, forms and SSE data), ViewTruncated (head and tail within MaxBytes), ViewPretty (indented JSON, "key: value" forms, or the decoded text; truncated when over budget) and ViewRaw (decoded bytes up to MaxBytes). An empty mode means ViewSummary; any other value is an error.
Types ¶
type Options ¶
type Options struct {
// MaxBytes is the body budget for the truncated, pretty and raw views
// (default DefaultMaxBytes; values above MaxBytesCap are clamped).
MaxBytes int
// StringTruncate elides strings longer than this in summary and schema
// views (default DefaultStringTruncate).
StringTruncate int
// Redact enables secret redaction of the rendered text.
Redact bool
// RevealSecrets is a per-call override that disables redaction even when
// Redact is set.
RevealSecrets bool
// ArraySample is the number of leading array elements a summary shows
// (default DefaultArraySample).
ArraySample int
}
Options tunes how Render shapes its output. The zero value is usable but disables redaction; use DefaultOptions for the recommended defaults.
func DefaultOptions ¶
func DefaultOptions() Options
DefaultOptions returns the recommended options: a 4 KiB budget, 200-char string elision, a three-element array sample and redaction enabled.