cdp

package
v0.13.0 Latest Latest
Warning

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

Go to latest
Published: Aug 20, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package cdp drives an already-running stealth browser over the Chrome DevTools Protocol to extract and inject browser storage state. It connects through the serve multiplexer's ?fingerprint=<seed> routing via chromedp's RemoteAllocator and never launches Chrome itself.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Inject

func Inject(ctx context.Context, cdpBase, seed string, st *StorageState, opt InjectOptions) error

Inject writes the storage state into the seed's fresh browser: cookies first (browser-global), then - unless CookiesOnly - per-origin localStorage on a scratch tab navigated to each origin.

Types

type Cookie struct {
	Name     string  `json:"name"`
	Value    string  `json:"value"`
	Domain   string  `json:"domain"`
	Path     string  `json:"path"`
	Expires  float64 `json:"expires"`
	HTTPOnly bool    `json:"httpOnly"`
	Secure   bool    `json:"secure"`
	SameSite string  `json:"sameSite,omitempty"`
}

Cookie mirrors a Playwright storageState cookie. Expires is seconds since the epoch, or -1 for a session cookie.

type InjectOptions added in v0.13.0

type InjectOptions struct {
	// CookiesOnly writes the cookies and stops. Cookies are browser-global and
	// land in a single call with no navigation; localStorage is origin-scoped and
	// can only be written from a page on that origin, so restoring it means
	// driving a tab through every origin in the snapshot - slow, and plainly
	// visible to anyone watching a headed browser. A durable profile dir already
	// holds its own localStorage, so that pass buys nothing there.
	CookiesOnly bool
	// OnOrigin, when set, is called before each origin is navigated (1-based
	// index, total). It exists so the daemon can say what the browser is doing
	// while it drives itself across the display.
	OnOrigin func(index, total int, origin string)
}

InjectOptions tunes a storage-state inject.

type LocalStorageItem

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

LocalStorageItem is a single localStorage key/value pair.

type Origin

type Origin struct {
	Origin       string             `json:"origin"`
	LocalStorage []LocalStorageItem `json:"localStorage"`
}

Origin is one origin's localStorage in the Playwright storageState shape.

type StorageState

type StorageState struct {
	Cookies []Cookie `json:"cookies"`
	Origins []Origin `json:"origins"`
}

StorageState is the subset of the Playwright storageState JSON shape cuttle checks out and back in: global cookies plus per-origin localStorage. It is small (auth state, not full Chrome-profile fidelity) so it round-trips over CDP between the local canonical copy and an ephemeral remote seed.

func Extract

func Extract(ctx context.Context, cdpBase, seed string, origins []string) (*StorageState, []string, error)

Extract connects to the seed's browser and reads its storage state WITHOUT perturbing the live session. Cookies are a pure browser-global Storage.getCookies read. localStorage is read IN PLACE from each already-open page target - never by navigating the scratch tab to a live origin. That navigation was the bug: the scratch tab shares the browser-global cookie jar, so re-fetching a live origin as the user's session let the server rotate a mid-login cookie (e.g. github.com's _gh_sess), invalidating the CSRF token bound to the login form the user was about to submit ("What? your browser did something unexpected"). A checkpoint now issues zero requests to any origin and cannot mutate the live jar.

origins is the set the caller expects to see (its prior snapshot's origins plus cookie-derived ones); any origin without an open tab to read is returned in failed so the caller carries its last-known localStorage forward rather than clearing it - closing a tab must not drop its persisted localStorage. Origins discovered from open tabs beyond that set are captured too, so a brand-new login is snapshotted on its very first checkpoint.

func (*StorageState) OriginURLs

func (s *StorageState) OriginURLs() []string

OriginURLs returns the origin strings the state carries, so a capture knows which origins to re-read localStorage from.

Jump to

Keyboard shortcuts

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