Help us shape the future of Go! Take the 2026 Go Developer Survey

har

package
v1.0.2 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

Documentation

Overview

Package har turns requests into catalog candidates: those of a HAR file (saved from the browser's developer tools while using the application) and those the recording proxy sees feed the same pipeline (Builder). Only requests to the target are taken, without static files, and of the headers only Accept and Content-Type: cookies and tokens never enter the catalog. A request whose query, body or path carries a credential or personal data is left out and reported, to be added by hand: a credential is a parameter or key named like one (password, currentPassword, authToken, jwt, ticket…) or a value shaped like one (a JWT, a long random token; see secret.go).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func MaskPath

func MaskPath(p string) string

MaskPath is a path as a note or the live output may print it: every segment shaped like a credential replaced by {token} and every one that holds personal data by {personal}; a path whose personal data no single segment holds is printed as /{personal}.

func Read

func Read(raw []byte, baseURL string) ([]Candidate, []Note, error)

Read parses a HAR file and returns the requests to baseURL, each once.

func ReadWith

func ReadWith(raw []byte, baseURL string, o Options) ([]Candidate, []Note, error)

ReadWith is Read with options: the same pipeline the proxy recording uses.

func Static

func Static(p string) bool

Static reports a path that is never a catalog candidate: a static file (script, style, image, font, media) or the noise of a development server (/_next/static, /_nuxt, /build, Vite, the favicon).

func Textual

func Textual(mt string) bool

Textual is a media type a scan for personal data can read.

Types

type Builder

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

Builder turns entries into candidates, each once.

func NewBuilder

func NewBuilder(baseURL string, o Options) (*Builder, error)

NewBuilder starts a pipeline for the requests to baseURL.

func (*Builder) Add

func (b *Builder) Add(e Entry) (*Candidate, *Note)

Add takes one entry. It returns the candidate when the entry is a new request, a note when it is left out for a reason the user should know, and neither for another host, a static file or a duplicate. The candidate stays the Builder's: a duplicate whose response holds personal data sets its Personal, so read that once every entry is in.

func (*Builder) Key

func (b *Builder) Key(r catalog.Request) string

Key tells requests apart the way Add does, so a catalog request that is already there can be recognised: with Options.Routes by service, method, route, query parameter names, identity and body shape; without, by the service, method, filled path and body.

type Candidate

type Candidate struct {
	Method  string
	Path    string // relative to the target, query included; {name} where a route parameter is
	Params  map[string]string
	Headers [][2]string
	Body    json.RawMessage
	Auth    bool // the browser sent Authorization or a cookie
	// Identity is the configured identity whose token the browser sent.
	Identity string
	// Route is the inventory route the request reaches (its path), when
	// Options.Routes is given.
	Route string
	// Personal: the response held personal data, so its body must be kept
	// private. The response itself is never kept.
	Personal bool
	// Multipart is a form with files: the fields are kept, every file is a
	// synthetic one of the same kind.
	Multipart *catalog.Multipart
}

Candidate is one request found in the file.

type Entry

type Entry struct {
	Method   string
	URL      string // absolute
	Headers  [][2]string
	MimeType string // of the body
	Text     string // the body
	// Response is the response body, only scanned for personal data when
	// Options.Personal is set; it is never kept.
	Response []byte
	// Unscanned: there was a response body, but not whole (over the cap, the
	// client went away, the HAR file left it out) or in an encoding that
	// cannot be read. It counts as personal data.
	Unscanned bool
	// contains filtered or unexported fields
}

Entry is one request as the browser saved it in a HAR file or as the recording proxy saw it. Headers are as sent, credentials included: the pipeline reads them to recognise an identity and never keeps them.

type Note

type Note struct {
	Request string
	Reason  string
}

Note is an entry that was left out, with the reason.

type Options

type Options struct {
	// Routes turns a path into its route: a {name} segment of the route
	// becomes a parameter of the candidate, and requests are told apart by
	// method, route, the names of the query parameters, identity and the
	// shape of the body (its keys and value types), so /users/1 and
	// /users/2, or a poll with a new ?since=, are one candidate. An empty
	// inventory keeps the paths as they are but still compares by shape.
	// Without Routes a request is a duplicate only when it is the same.
	Routes *routes.Inventory
	Target string // the service, as the inventory names it
	// Identify returns the configured identity whose token the request
	// carries, or "".
	Identify func(authorization, cookie string) string
	// Personal scans Entry.Response for personal data (Candidate.Personal).
	Personal bool
}

Options extend the pipeline beyond the plain HAR reading of Read.

Jump to

Keyboard shortcuts

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