mirror of
https://github.com/projectdiscovery/nuclei.git
synced 2025-12-22 06:15:26 +00:00
Feat conn (#3991)
* . * introducing connection reuse with scan strategy * bumping up to 500 probably should be set to a lower number to push connection reuse * Removed debug panic * merge conflict fix * dep update * removing useless comparison * lint errs * fmt --------- Co-authored-by: Ice3man <nizamulrana@gmail.com> Co-authored-by: sandeep <8293321+ehsandeep@users.noreply.github.com>
This commit is contained in:
parent
5bd4e68771
commit
28be967643
@ -16,6 +16,7 @@ import (
|
|||||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols"
|
"github.com/projectdiscovery/nuclei/v2/pkg/protocols"
|
||||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/contextargs"
|
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/contextargs"
|
||||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/http/httpclientpool"
|
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/http/httpclientpool"
|
||||||
|
httputil "github.com/projectdiscovery/nuclei/v2/pkg/protocols/utils/http"
|
||||||
"github.com/projectdiscovery/nuclei/v2/pkg/templates"
|
"github.com/projectdiscovery/nuclei/v2/pkg/templates"
|
||||||
"github.com/projectdiscovery/nuclei/v2/pkg/templates/types"
|
"github.com/projectdiscovery/nuclei/v2/pkg/templates/types"
|
||||||
"github.com/projectdiscovery/retryablehttp-go"
|
"github.com/projectdiscovery/retryablehttp-go"
|
||||||
@ -58,13 +59,13 @@ func New(opts Options) (*Service, error) {
|
|||||||
|
|
||||||
var mappingData map[string]string
|
var mappingData map[string]string
|
||||||
config := config.DefaultConfig
|
config := config.DefaultConfig
|
||||||
if err == nil {
|
|
||||||
mappingFile := filepath.Join(config.TemplatesDirectory, mappingFilename)
|
mappingFile := filepath.Join(config.TemplatesDirectory, mappingFilename)
|
||||||
if file, err := os.Open(mappingFile); err == nil {
|
if file, err := os.Open(mappingFile); err == nil {
|
||||||
_ = yaml.NewDecoder(file).Decode(&mappingData)
|
_ = yaml.NewDecoder(file).Decode(&mappingData)
|
||||||
file.Close()
|
file.Close()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if opts.ExecuterOpts.Options.Verbose {
|
if opts.ExecuterOpts.Options.Verbose {
|
||||||
gologger.Verbose().Msgf("Normalized mapping (%d): %v\n", len(mappingData), mappingData)
|
gologger.Verbose().Msgf("Normalized mapping (%d): %v\n", len(mappingData), mappingData)
|
||||||
}
|
}
|
||||||
@ -86,7 +87,9 @@ func New(opts Options) (*Service, error) {
|
|||||||
childExecuter := opts.Engine.ChildExecuter()
|
childExecuter := opts.Engine.ChildExecuter()
|
||||||
|
|
||||||
httpclient, err := httpclientpool.Get(opts.ExecuterOpts.Options, &httpclientpool.Configuration{
|
httpclient, err := httpclientpool.Get(opts.ExecuterOpts.Options, &httpclientpool.Configuration{
|
||||||
Connection: &httpclientpool.ConnectionConfiguration{DisableKeepAlive: true},
|
Connection: &httpclientpool.ConnectionConfiguration{
|
||||||
|
DisableKeepAlive: httputil.ShouldDisableKeepAlive(opts.ExecuterOpts.Options),
|
||||||
|
},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not get http client")
|
return nil, errors.Wrap(err, "could not get http client")
|
||||||
|
|||||||
@ -20,6 +20,7 @@ import (
|
|||||||
protocolutils "github.com/projectdiscovery/nuclei/v2/pkg/protocols/utils"
|
protocolutils "github.com/projectdiscovery/nuclei/v2/pkg/protocols/utils"
|
||||||
httputil "github.com/projectdiscovery/nuclei/v2/pkg/protocols/utils/http"
|
httputil "github.com/projectdiscovery/nuclei/v2/pkg/protocols/utils/http"
|
||||||
"github.com/projectdiscovery/nuclei/v2/pkg/types"
|
"github.com/projectdiscovery/nuclei/v2/pkg/types"
|
||||||
|
"github.com/projectdiscovery/nuclei/v2/pkg/types/scanstrategy"
|
||||||
"github.com/projectdiscovery/rawhttp"
|
"github.com/projectdiscovery/rawhttp"
|
||||||
"github.com/projectdiscovery/retryablehttp-go"
|
"github.com/projectdiscovery/retryablehttp-go"
|
||||||
errorutil "github.com/projectdiscovery/utils/errors"
|
errorutil "github.com/projectdiscovery/utils/errors"
|
||||||
@ -341,7 +342,7 @@ func (r *requestGenerator) fillRequest(req *retryablehttp.Request, values map[st
|
|||||||
}
|
}
|
||||||
|
|
||||||
// In case of multiple threads the underlying connection should remain open to allow reuse
|
// In case of multiple threads the underlying connection should remain open to allow reuse
|
||||||
if r.request.Threads <= 0 && req.Header.Get("Connection") == "" {
|
if r.request.Threads <= 0 && req.Header.Get("Connection") == "" && r.options.Options.ScanStrategy != scanstrategy.HostSpray.String() {
|
||||||
req.Close = true
|
req.Close = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import (
|
|||||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/fuzz"
|
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/fuzz"
|
||||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/generators"
|
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/generators"
|
||||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/http/httpclientpool"
|
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/http/httpclientpool"
|
||||||
|
httputil "github.com/projectdiscovery/nuclei/v2/pkg/protocols/utils/http"
|
||||||
"github.com/projectdiscovery/rawhttp"
|
"github.com/projectdiscovery/rawhttp"
|
||||||
"github.com/projectdiscovery/retryablehttp-go"
|
"github.com/projectdiscovery/retryablehttp-go"
|
||||||
fileutil "github.com/projectdiscovery/utils/file"
|
fileutil "github.com/projectdiscovery/utils/file"
|
||||||
@ -249,7 +250,9 @@ func (request *Request) Compile(options *protocols.ExecutorOptions) error {
|
|||||||
MaxRedirects: request.MaxRedirects,
|
MaxRedirects: request.MaxRedirects,
|
||||||
NoTimeout: false,
|
NoTimeout: false,
|
||||||
CookieReuse: request.CookieReuse,
|
CookieReuse: request.CookieReuse,
|
||||||
Connection: &httpclientpool.ConnectionConfiguration{DisableKeepAlive: true},
|
Connection: &httpclientpool.ConnectionConfiguration{
|
||||||
|
DisableKeepAlive: httputil.ShouldDisableKeepAlive(options.Options),
|
||||||
|
},
|
||||||
RedirectFlow: httpclientpool.DontFollowRedirect,
|
RedirectFlow: httpclientpool.DontFollowRedirect,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,8 +21,10 @@ import (
|
|||||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/protocolstate"
|
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/protocolstate"
|
||||||
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/utils"
|
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/utils"
|
||||||
"github.com/projectdiscovery/nuclei/v2/pkg/types"
|
"github.com/projectdiscovery/nuclei/v2/pkg/types"
|
||||||
|
"github.com/projectdiscovery/nuclei/v2/pkg/types/scanstrategy"
|
||||||
"github.com/projectdiscovery/rawhttp"
|
"github.com/projectdiscovery/rawhttp"
|
||||||
"github.com/projectdiscovery/retryablehttp-go"
|
"github.com/projectdiscovery/retryablehttp-go"
|
||||||
|
mapsutil "github.com/projectdiscovery/utils/maps"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -31,9 +33,8 @@ var (
|
|||||||
|
|
||||||
rawHttpClient *rawhttp.Client
|
rawHttpClient *rawhttp.Client
|
||||||
forceMaxRedirects int
|
forceMaxRedirects int
|
||||||
poolMutex *sync.RWMutex
|
|
||||||
normalClient *retryablehttp.Client
|
normalClient *retryablehttp.Client
|
||||||
clientPool map[string]*retryablehttp.Client
|
clientPool *mapsutil.SyncLockMap[string, *retryablehttp.Client]
|
||||||
)
|
)
|
||||||
|
|
||||||
// Init initializes the clientpool implementation
|
// Init initializes the clientpool implementation
|
||||||
@ -45,8 +46,9 @@ func Init(options *types.Options) error {
|
|||||||
if options.ShouldFollowHTTPRedirects() {
|
if options.ShouldFollowHTTPRedirects() {
|
||||||
forceMaxRedirects = options.MaxRedirects
|
forceMaxRedirects = options.MaxRedirects
|
||||||
}
|
}
|
||||||
poolMutex = &sync.RWMutex{}
|
clientPool = &mapsutil.SyncLockMap[string, *retryablehttp.Client]{
|
||||||
clientPool = make(map[string]*retryablehttp.Client)
|
Map: make(mapsutil.Map[string, *retryablehttp.Client]),
|
||||||
|
}
|
||||||
|
|
||||||
client, err := wrappedGet(options, &Configuration{})
|
client, err := wrappedGet(options, &Configuration{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -160,12 +162,9 @@ func wrappedGet(options *types.Options, configuration *Configuration) (*retryabl
|
|||||||
}
|
}
|
||||||
|
|
||||||
hash := configuration.Hash()
|
hash := configuration.Hash()
|
||||||
poolMutex.RLock()
|
if client, ok := clientPool.Get(hash); ok {
|
||||||
if client, ok := clientPool[hash]; ok {
|
|
||||||
poolMutex.RUnlock()
|
|
||||||
return client, nil
|
return client, nil
|
||||||
}
|
}
|
||||||
poolMutex.RUnlock()
|
|
||||||
|
|
||||||
// Multiple Host
|
// Multiple Host
|
||||||
retryableHttpOptions := retryablehttp.DefaultOptionsSpraying
|
retryableHttpOptions := retryablehttp.DefaultOptionsSpraying
|
||||||
@ -174,7 +173,7 @@ func wrappedGet(options *types.Options, configuration *Configuration) (*retryabl
|
|||||||
maxConnsPerHost := 0
|
maxConnsPerHost := 0
|
||||||
maxIdleConnsPerHost := -1
|
maxIdleConnsPerHost := -1
|
||||||
|
|
||||||
if configuration.Threads > 0 {
|
if configuration.Threads > 0 || options.ScanStrategy == scanstrategy.HostSpray.String() {
|
||||||
// Single host
|
// Single host
|
||||||
retryableHttpOptions = retryablehttp.DefaultOptionsSingle
|
retryableHttpOptions = retryablehttp.DefaultOptionsSingle
|
||||||
disableKeepAlives = false
|
disableKeepAlives = false
|
||||||
@ -203,6 +202,7 @@ func wrappedGet(options *types.Options, configuration *Configuration) (*retryabl
|
|||||||
redirectFlow = DontFollowRedirect
|
redirectFlow = DontFollowRedirect
|
||||||
maxRedirects = 0
|
maxRedirects = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// override connection's settings if required
|
// override connection's settings if required
|
||||||
if configuration.Connection != nil {
|
if configuration.Connection != nil {
|
||||||
disableKeepAlives = configuration.Connection.DisableKeepAlive
|
disableKeepAlives = configuration.Connection.DisableKeepAlive
|
||||||
@ -298,9 +298,9 @@ func wrappedGet(options *types.Options, configuration *Configuration) (*retryabl
|
|||||||
|
|
||||||
// Only add to client pool if we don't have a cookie jar in place.
|
// Only add to client pool if we don't have a cookie jar in place.
|
||||||
if jar == nil {
|
if jar == nil {
|
||||||
poolMutex.Lock()
|
if err := clientPool.Set(hash, client); err != nil {
|
||||||
clientPool[hash] = client
|
return nil, err
|
||||||
poolMutex.Unlock()
|
}
|
||||||
}
|
}
|
||||||
return client, nil
|
return client, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import (
|
|||||||
"go.uber.org/multierr"
|
"go.uber.org/multierr"
|
||||||
"moul.io/http2curl"
|
"moul.io/http2curl"
|
||||||
|
|
||||||
|
"github.com/projectdiscovery/fastdialer/fastdialer"
|
||||||
"github.com/projectdiscovery/gologger"
|
"github.com/projectdiscovery/gologger"
|
||||||
"github.com/projectdiscovery/nuclei/v2/pkg/operators"
|
"github.com/projectdiscovery/nuclei/v2/pkg/operators"
|
||||||
"github.com/projectdiscovery/nuclei/v2/pkg/output"
|
"github.com/projectdiscovery/nuclei/v2/pkg/output"
|
||||||
@ -878,7 +879,7 @@ func (request *Request) pruneSignatureInternalValues(maps ...map[string]interfac
|
|||||||
|
|
||||||
func (request *Request) newContext(input *contextargs.Context) context.Context {
|
func (request *Request) newContext(input *contextargs.Context) context.Context {
|
||||||
if input.MetaInput.CustomIP != "" {
|
if input.MetaInput.CustomIP != "" {
|
||||||
return context.WithValue(context.Background(), "ip", input.MetaInput.CustomIP) //nolint
|
return context.WithValue(context.Background(), fastdialer.IP, input.MetaInput.CustomIP)
|
||||||
}
|
}
|
||||||
return context.Background()
|
return context.Background()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,8 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/projectdiscovery/nuclei/v2/pkg/types"
|
||||||
|
"github.com/projectdiscovery/nuclei/v2/pkg/types/scanstrategy"
|
||||||
"github.com/projectdiscovery/retryablehttp-go"
|
"github.com/projectdiscovery/retryablehttp-go"
|
||||||
urlutil "github.com/projectdiscovery/utils/url"
|
urlutil "github.com/projectdiscovery/utils/url"
|
||||||
)
|
)
|
||||||
@ -42,3 +44,9 @@ func SetHeader(req *retryablehttp.Request, name, value string) {
|
|||||||
req.Host = value
|
req.Host = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ShouldDisableKeepAlive depending on scan strategy
|
||||||
|
func ShouldDisableKeepAlive(options *types.Options) bool {
|
||||||
|
// with host-spray strategy keep-alive must be enabled
|
||||||
|
return options.ScanStrategy != scanstrategy.HostSpray.String()
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user