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 ¶
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 ¶
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 ¶
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.