har

package
v1.55.0 Latest Latest
Warning

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

Go to latest
Published: Aug 4, 2026 License: Apache-2.0 Imports: 17 Imported by: 8

Documentation

Overview

Package har provides HAR 1.2 types and an HTTP client middleware for capturing outbound request/response pairs for troubleshooting.

Index

Constants

View Source
const CreatorName = "flanksource-commons"

CreatorName identifies commons as the producer in the HAR envelope.

View Source
const MaxBodySizeProperty = "http.har.maxBodySize"

MaxBodySizeProperty is the -P/properties key that overrides the default per-body capture cap (in bytes). Set e.g. -P http.har.maxBodySize=1048576 to capture request/response bodies larger than the 64 KB default, or -P http.har.maxBodySize=0 to capture full bodies with no cap.

View Source
const PropertyPrefix = "http."

PropertyPrefix is the namespace the registry resolves its properties under.

View Source
const SensitiveProperty = "http.har.sensitive"

SensitiveProperty is the -P/properties key that disables redaction. By default credentials in headers, bodies and query strings are masked, so a HAR file is safe to share but cannot be replayed. Set -P http.har.sensitive=true to capture them verbatim — the resulting file holds live secrets and is written with 0600.

Variables

This section is empty.

Functions

func NewMetadataMiddleware added in v1.55.0

func NewMetadataMiddleware(cfg HARConfig, handler func(*Entry)) middlewares.Middleware

NewMetadataMiddleware captures method, URL, sanitized headers, query string, status and timings — no request or response bodies. Body sizes use -1 per the HAR spec ("size unknown"). Use it when you want a HAR file for traffic analysis without paying the body-buffering cost.

Ported from duty/connection/common.go's metadataHARMiddleware, which commons/http and commons-db each carried their own copy of.

func NewMiddleware

func NewMiddleware(cfg HARConfig, handler func(*Entry)) middlewares.Middleware

NewMiddleware returns a middlewares.Middleware that captures each request/response pair into a *Entry and calls handler. If handler is nil, the middleware is a no-op.

func WriteFile added in v1.55.0

func WriteFile(collector *Collector, path string) error

WriteFile serializes collector.Entries() into a HAR 1.2 file at path. A collector configured with CaptureSensitive holds unmasked credentials, so its file is written 0600 rather than 0644.

Types

type Cache

type Cache struct{}

Cache holds cache information for an entry (required by spec; left empty by hx).

type Collector

type Collector struct {
	Config HARConfig
	// contains filtered or unexported fields
}

Collector accumulates HAR entries from multiple sources (main requests, OAuth token fetches, redirect hops, retries).

func NewCollector

func NewCollector(cfg HARConfig) *Collector

func (*Collector) Add

func (c *Collector) Add(e *Entry)

Add appends an entry to the collector. Safe for concurrent use.

func (*Collector) Entries

func (c *Collector) Entries() []Entry

Entries returns a copy of all collected entries.

func (*Collector) Handler

func (c *Collector) Handler() func(*Entry)

Handler returns a func(*Entry) that adds entries to this collector. Useful for passing to components that accept a HAR handler callback.

func (*Collector) Middleware

func (c *Collector) Middleware() middlewares.Middleware

Middleware returns a transport middleware that captures each request/response into this collector.

func (*Collector) Pretty added in v1.48.0

func (c *Collector) Pretty() api.Text

Pretty returns a compact summary of all collected entries.

func (*Collector) Table added in v1.48.0

func (c *Collector) Table() api.TextTable

Table returns a TextTable of all collected entries with row detail expansion.

type Content

type Content struct {
	Size      int64  `json:"size"`
	MimeType  string `json:"mimeType,omitempty"`
	Text      string `json:"text,omitempty"`
	Truncated bool   `json:"truncated,omitempty"`
}

Content holds the response body details.

type Cookie struct {
	Name  string `json:"name"`
	Value string `json:"value"`
}

Cookie is a name/value pair from a Cookie or Set-Cookie header.

type Creator

type Creator struct {
	Name    string `json:"name"`
	Version string `json:"version"`
}

Creator identifies the application that created the HAR log.

type Entry

type Entry struct {
	StartedDateTime string   `json:"startedDateTime"`
	Time            float64  `json:"time"`
	Request         Request  `json:"request"`
	Response        Response `json:"response"`
	Cache           Cache    `json:"cache"`
	Timings         Timings  `json:"timings"`
}

Entry represents a single HTTP request/response pair.

func CaptureRedirect

func CaptureRedirect(req *http.Request, resp *http.Response, cfg HARConfig) *Entry

CaptureRedirect builds a HAR entry from a redirect hop's request and response.

func (Entry) Columns added in v1.48.0

func (e Entry) Columns() []api.ColumnDef

Columns implements api.TableProvider.

func (Entry) Pretty added in v1.48.0

func (e Entry) Pretty() api.Text

Pretty returns a compact one-line summary.

func (Entry) Row added in v1.48.0

func (e Entry) Row() map[string]any

Row implements api.TableProvider.

func (Entry) RowDetail added in v1.48.0

func (e Entry) RowDetail() api.Textable

RowDetail implements api.DetailProvider for expandable table rows.

type File

type File struct {
	Log Log `json:"log"`
}

File is the outermost HAR 1.2 envelope: {"log": {...}}. Use this when writing .har files for import into browser DevTools.

type HARConfig

type HARConfig struct {
	// MaxBodySize is the maximum number of bytes captured per body.
	// Bodies exceeding this are truncated and Content.Truncated is set to true.
	// Default: 65536 (64 KB).
	MaxBodySize int64

	// CaptureContentTypes lists MIME type prefixes for which body capture is enabled.
	// Default: ["application/json", "application/x-www-form-urlencoded"].
	CaptureContentTypes []string

	// RedactedHeaders lists additional header name glob patterns to redact,
	// on top of logger.CommonRedactedHeaders.
	RedactedHeaders []string

	// RedactedBodyKeys lists additional key names (case-insensitive substring
	// match) to redact from request/response bodies (JSON and form) and from
	// URL query strings, on top of logger.SensitiveKeys. Use for app-specific
	// identifiers (e.g. session ids, national-id fields) that the default
	// heuristics don't recognise.
	RedactedBodyKeys []string

	// CaptureSensitive records credentials verbatim instead of masking them,
	// so the archive can be replayed against the live API. Honours
	// SensitiveProperty; off by default.
	CaptureSensitive bool
}

HARConfig controls what the HAR middleware captures and how it redacts.

func DefaultConfig

func DefaultConfig() HARConfig

DefaultConfig returns a HARConfig with sensible defaults. The per-body capture cap honours the MaxBodySizeProperty (-P http.har.maxBodySize=…) override; an unset or unparseable value keeps the 64 KB default, and a value <= 0 disables truncation (full bodies captured).

type Header struct {
	Name  string `json:"name"`
	Value string `json:"value"`
}

Header is a name/value pair.

type Level added in v1.55.0

type Level int

Level selects what a HAR collector captures. Borrowed from duty/connection/common.go's Debug/Trace split: at Metadata only headers, query strings and timings are recorded (no bodies, so no body re-read cost); at Full the standard collector middleware captures bodies too.

const (
	Disabled Level = iota
	Metadata
	Full
)

func ParseLevel added in v1.55.0

func ParseLevel(value string, def Level) (Level, error)

ParseLevel maps a property value onto a Level. "debug"/"trace" are accepted as synonyms for metadata/full, matching the log.level.*.har vocabulary duty and commons-db use. An empty string yields def; anything unrecognised is an error, so a typo turns into a startup failure rather than silently capturing the wrong thing.

func (Level) String added in v1.55.0

func (l Level) String() string

type Log

type Log struct {
	Version string  `json:"version"`
	Creator Creator `json:"creator"`
	Pages   []Page  `json:"pages"`
	Entries []Entry `json:"entries"`
}

Log is the top-level HAR 1.2 container.

type Page

type Page struct {
	StartedDateTime string      `json:"startedDateTime"`
	ID              string      `json:"id"`
	Title           string      `json:"title"`
	PageTimings     PageTimings `json:"pageTimings"`
}

Page is included for HAR 1.2 spec compliance; hx leaves it empty.

type PageTimings

type PageTimings struct {
	OnLoad int `json:"onLoad,omitempty"`
}

PageTimings holds page-level timing data (unused by hx, present for spec compliance).

type PostData

type PostData struct {
	MimeType string `json:"mimeType"`
	Text     string `json:"text"`
}

PostData holds the request body details.

type QueryString

type QueryString struct {
	Name  string `json:"name"`
	Value string `json:"value"`
}

QueryString is a name/value pair from the URL query string.

type Registry added in v1.55.0

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

Registry turns -P properties into HAR capture: it resolves the output path and level per feature, owns one collector per output file, and writes them all on Flush.

Properties are looked up per-feature first, then globally:

http.<feature>.har        / http.har        output path; unset disables capture
http.<feature>.har.level  / http.har.level  "full" (default) or "metadata"
http.har.sensitive                          capture credentials verbatim
http.har.maxBodySize                        per-body capture cap

Collectors are deduplicated by absolute path, so several features writing to the same file share one archive.

func NewRegistry added in v1.55.0

func NewRegistry(log logger.Logger) *Registry

NewRegistry returns a registry that announces capture as it is enabled and reports flush results on log. Pass nil for the shared "har" logger, whose level can be raised on its own with -Plog.level.har=debug.

func (*Registry) Flush added in v1.55.0

func (r *Registry) Flush() error

Flush writes every collector to its file. Collectors are kept afterwards, so a second call rewrites the same files rather than losing entries.

func (*Registry) For added in v1.55.0

func (r *Registry) For(feature string) (*Collector, string, Level, error)

For reports the collector, absolute output path and level configured for feature. A nil collector means capture is off. The shape matches http.CommonsHTTPContext's HARFor apart from the error, which reports an unusable http.har.level rather than silently capturing the wrong thing.

func (*Registry) Transport added in v1.55.0

func (r *Registry) Transport(feature string, base http.RoundTripper) (http.RoundTripper, error)

Transport wraps base with the capture middleware configured for feature, or returns base unchanged when capture is off.

type Request

type Request struct {
	Method      string        `json:"method"`
	URL         string        `json:"url"`
	HTTPVersion string        `json:"httpVersion"`
	Cookies     []Cookie      `json:"cookies"`
	Headers     []Header      `json:"headers"`
	QueryString []QueryString `json:"queryString"`
	PostData    *PostData     `json:"postData,omitempty"`
	HeadersSize int           `json:"headersSize"`
	BodySize    int64         `json:"bodySize"`
}

Request holds HAR request data.

type Response

type Response struct {
	Status      int      `json:"status"`
	StatusText  string   `json:"statusText"`
	HTTPVersion string   `json:"httpVersion"`
	Cookies     []Cookie `json:"cookies"`
	Headers     []Header `json:"headers"`
	Content     Content  `json:"content"`
	RedirectURL string   `json:"redirectURL"`
	HeadersSize int      `json:"headersSize"`
	BodySize    int64    `json:"bodySize"`
}

Response holds HAR response data.

type Timings

type Timings struct {
	Send    float64 `json:"send"`
	Wait    float64 `json:"wait"`
	Receive float64 `json:"receive"`
}

Timings records durations (in milliseconds) for the request lifecycle.

Jump to

Keyboard shortcuts

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