Path: blob/dev/pkg/protocols/headless/engine/instance.go
2072 views
package engine12import (3"context"4"errors"5"time"67"github.com/go-rod/rod"8"github.com/go-rod/rod/lib/utils"9"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/interactsh"10)1112// Instance is an isolated browser instance opened for doing operations with it.13type Instance struct {14browser *Browser15engine *rod.Browser1617// redundant due to dependency cycle18interactsh *interactsh.Client19requestLog map[string]string // contains actual request that was sent20}2122// NewInstance creates a new instance for the current browser.23//24// The login process is repeated only once for a browser, and the created25// isolated browser instance is used for entire navigation one by one.26//27// Users can also choose to run the login->actions process again28// which uses a new incognito browser instance to run actions.29func (b *Browser) NewInstance() (*Instance, error) {30browser, err := b.engine.Incognito()31if err != nil {32return nil, err33}3435// We use a custom sleeper that sleeps from 100ms to 500 ms waiting36// for an interaction. Used throughout rod for clicking, etc.37browser = browser.Sleeper(func() utils.Sleeper { return maxBackoffSleeper(10) })38return &Instance{browser: b, engine: browser, requestLog: map[string]string{}}, nil39}4041// returns a map of [template-defined-urls] -> [actual-request-sent]42// Note: this does not include CORS or other requests while rendering that were not explicitly43// specified in template44func (i *Instance) GetRequestLog() map[string]string {45return i.requestLog46}4748// Close closes all the tabs and pages for a browser instance49func (i *Instance) Close() error {50return i.engine.Close()51}5253// SetInteractsh client54func (i *Instance) SetInteractsh(interactsh *interactsh.Client) {55i.interactsh = interactsh56}5758// maxBackoffSleeper is a backoff sleeper respecting max backoff values59func maxBackoffSleeper(max int) utils.Sleeper {60count := 061backoffSleeper := utils.BackoffSleeper(100*time.Millisecond, 500*time.Millisecond, nil)6263return func(ctx context.Context) error {64if ctx.Err() != nil {65return ctx.Err()66}67if count == max {68return errors.New("max sleep count")69}70count++71return backoffSleeper(ctx)72}73}747576