Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/protocols/headless/engine/instance.go
2072 views
1
package engine
2
3
import (
4
"context"
5
"errors"
6
"time"
7
8
"github.com/go-rod/rod"
9
"github.com/go-rod/rod/lib/utils"
10
"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/interactsh"
11
)
12
13
// Instance is an isolated browser instance opened for doing operations with it.
14
type Instance struct {
15
browser *Browser
16
engine *rod.Browser
17
18
// redundant due to dependency cycle
19
interactsh *interactsh.Client
20
requestLog map[string]string // contains actual request that was sent
21
}
22
23
// NewInstance creates a new instance for the current browser.
24
//
25
// The login process is repeated only once for a browser, and the created
26
// isolated browser instance is used for entire navigation one by one.
27
//
28
// Users can also choose to run the login->actions process again
29
// which uses a new incognito browser instance to run actions.
30
func (b *Browser) NewInstance() (*Instance, error) {
31
browser, err := b.engine.Incognito()
32
if err != nil {
33
return nil, err
34
}
35
36
// We use a custom sleeper that sleeps from 100ms to 500 ms waiting
37
// for an interaction. Used throughout rod for clicking, etc.
38
browser = browser.Sleeper(func() utils.Sleeper { return maxBackoffSleeper(10) })
39
return &Instance{browser: b, engine: browser, requestLog: map[string]string{}}, nil
40
}
41
42
// returns a map of [template-defined-urls] -> [actual-request-sent]
43
// Note: this does not include CORS or other requests while rendering that were not explicitly
44
// specified in template
45
func (i *Instance) GetRequestLog() map[string]string {
46
return i.requestLog
47
}
48
49
// Close closes all the tabs and pages for a browser instance
50
func (i *Instance) Close() error {
51
return i.engine.Close()
52
}
53
54
// SetInteractsh client
55
func (i *Instance) SetInteractsh(interactsh *interactsh.Client) {
56
i.interactsh = interactsh
57
}
58
59
// maxBackoffSleeper is a backoff sleeper respecting max backoff values
60
func maxBackoffSleeper(max int) utils.Sleeper {
61
count := 0
62
backoffSleeper := utils.BackoffSleeper(100*time.Millisecond, 500*time.Millisecond, nil)
63
64
return func(ctx context.Context) error {
65
if ctx.Err() != nil {
66
return ctx.Err()
67
}
68
if count == max {
69
return errors.New("max sleep count")
70
}
71
count++
72
return backoffSleeper(ctx)
73
}
74
}
75
76