Documentation
¶
Overview ¶
Package har provides HAR 1.2 types and an HTTP client middleware for capturing outbound request/response pairs for troubleshooting.
Index ¶
- Constants
- func NewMetadataMiddleware(cfg HARConfig, handler func(*Entry)) middlewares.Middleware
- func NewMiddleware(cfg HARConfig, handler func(*Entry)) middlewares.Middleware
- func WriteFile(collector *Collector, path string) error
- type Cache
- type Collector
- func (c *Collector) Add(e *Entry)
- func (c *Collector) CaptureError() error
- func (c *Collector) DroppedEntries() int
- func (c *Collector) Entries() []Entry
- func (c *Collector) Handler() func(*Entry)
- func (c *Collector) MetadataMiddleware() middlewares.Middleware
- func (c *Collector) Middleware() middlewares.Middleware
- func (c *Collector) Pretty() api.Text
- func (c *Collector) Table() api.TextTable
- type Content
- type Cookie
- type Creator
- type DetailOptions
- type Entry
- type File
- type HARConfig
- type Header
- type Level
- type Log
- type Page
- type PageTimings
- type PostData
- type QueryString
- type Registry
- type Request
- type Response
- type Timings
Constants ¶
const CreatorName = "flanksource-commons"
CreatorName identifies commons as the producer in the HAR envelope.
const MaxBodySizeProperty = "http.har.response.body.length"
MaxBodySizeProperty is the -P/properties key that overrides the default per-body capture cap (in bytes). Set e.g. -P http.har.response.body.length=1048576 to lower the request/response cap, or set it to 0 to capture full bodies with no cap.
const PropertyPrefix = "http."
PropertyPrefix is the namespace the registry resolves its properties under.
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. handler receives each entry once the request completes; use Collector.MetadataMiddleware to also see requests while they are in flight.
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 once the request completes. If handler is nil, the middleware is a no-op. Use Collector.Middleware to also see requests while they are in flight.
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). Requests captured through its own middlewares are also tracked while in flight, so Entries can show a request that has not returned yet.
func NewCollector ¶
func NewCollectorWithHandler ¶ added in v1.57.0
NewCollectorWithHandler creates a collector that retains its own bounded view and forwards every completed entry to handler. This lets a request-scoped diagnostic collector coexist with a longer-lived HAR export collector. In-flight entries are never forwarded.
func NewCollectorWithLifecycle ¶ added in v1.60.0
NewCollectorWithLifecycle forwards both states of each request to a durable owner. It does not retain completed entries or their bodies in memory. Callback errors are available through CaptureError; they do not change the HTTP response returned by the wrapped transport.
func (*Collector) CaptureError ¶ added in v1.60.0
func (*Collector) DroppedEntries ¶ added in v1.57.0
DroppedEntries returns the number of entries rejected after MaxEntries was reached.
func (*Collector) Entries ¶
Entries returns a copy of the completed entries in completion order, followed by a snapshot of the requests still in flight in the order they started. An in-flight entry has Pending set and Time/Timings.Wait holding the elapsed milliseconds; it does not count toward MaxEntries.
func (*Collector) Handler ¶
Handler returns a func(*Entry) that adds entries to this collector. Useful for passing to components that accept a HAR handler callback.
func (*Collector) MetadataMiddleware ¶ added in v1.60.0
func (c *Collector) MetadataMiddleware() middlewares.Middleware
MetadataMiddleware is the collector-backed form of NewMetadataMiddleware: headers and timings only, with the request tracked as pending until it completes.
func (*Collector) Middleware ¶
func (c *Collector) Middleware() middlewares.Middleware
Middleware returns a transport middleware that captures each request/response into this collector, tracking the request as pending until it completes.
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 DetailOptions ¶ added in v1.57.0
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"`
ID string `json:"_id,omitempty"`
Pending bool `json:"_pending,omitempty"`
Error string `json:"_error,omitempty"`
}
Entry represents a single HTTP request/response pair.
ID, Pending and Error are HAR 1.2 custom fields (underscore-prefixed). ID is assigned by a Collector when it starts tracking the request and is kept by its completed entry, so a viewer can follow one round trip from pending to completed; each redirect hop and retry attempt is its own round trip with its own ID. Entries captured by the handler-only middlewares have no ID. Pending marks a snapshot of a request still in flight, whose Time and Timings.Wait are the elapsed milliseconds when the snapshot was taken. Error is the transport or body-read error the request ended with.
func (Entry) Detail ¶ added in v1.57.0
func (e Entry) Detail(options DetailOptions) api.Textable
Detail returns only the selected request and response sections.
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 {
// MaxEntries limits how many entries a Collector retains. Zero keeps all
// entries, which preserves the existing HAR-file behavior. Request-scoped
// diagnostics set an explicit bound.
MaxEntries int
// MaxBodySize is the maximum number of bytes captured per body.
// Bodies exceeding this are truncated and Content.Truncated is set to true.
// Default: 4194304 (4 MiB).
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.response.body.length=…) override, which accepts a plain byte count or a size suffix ("1048576", "1MiB", "4MB"); an unset or unparseable value keeps the 4 MiB default, and a value <= 0 disables truncation (full bodies captured).
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.
func ParseLevel ¶ added in v1.55.0
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.
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 QueryString ¶
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.response.body.length 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
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
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
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.