nuclei/v2/pkg/protocols/http/request_generator.go

82 lines
2.6 KiB
Go
Raw Normal View History

package http
2021-04-16 16:56:41 +05:30
import (
"github.com/projectdiscovery/nuclei/v2/pkg/protocols"
"github.com/projectdiscovery/nuclei/v2/pkg/protocols/common/generators"
)
// requestGenerator generates requests sequentially based on various
// configurations for a http request template.
//
// If payload values are present, an iterator is created for the payload
// values. Paths and Raw requests are supported as base input, so
// it will automatically select between them based on the template.
type requestGenerator struct {
currentIndex int
currentPayloads map[string]interface{}
okCurrentPayload bool
request *Request
options *protocols.ExecuterOptions
payloadIterator *generators.Iterator
interactshURLs []string
}
// LeaveDefaultPorts skips normalization of default standard ports
var LeaveDefaultPorts = false
// newGenerator creates a new request generator instance
func (request *Request) newGenerator() *requestGenerator {
generator := &requestGenerator{request: request, options: request.options}
if len(request.Payloads) > 0 {
generator.payloadIterator = request.generator.NewIterator()
}
return generator
}
// nextValue returns the next path or the next raw request depending on user input
// It returns false if all the inputs have been exhausted by the generator instance.
2021-02-26 13:13:11 +05:30
func (r *requestGenerator) nextValue() (value string, payloads map[string]interface{}, result bool) {
// Iterate each payload sequentially for each request path/raw
//
// If the sequence has finished for the current payload values
// then restart the sequence from the beginning and move on to the next payloads values
// otherwise use the last request.
var sequence []string
switch {
case len(r.request.Path) > 0:
sequence = r.request.Path
case len(r.request.Raw) > 0:
sequence = r.request.Raw
default:
return "", nil, false
}
hasPayloadIterator := r.payloadIterator != nil
hasInitializedPayloads := r.currentPayloads != nil
if r.currentIndex == 0 && hasPayloadIterator && !hasInitializedPayloads {
r.currentPayloads, r.okCurrentPayload = r.payloadIterator.Value()
}
if r.currentIndex < len(sequence) {
currentRequest := sequence[r.currentIndex]
r.currentIndex++
return currentRequest, r.currentPayloads, true
}
if r.currentIndex == len(sequence) {
if r.okCurrentPayload {
r.currentIndex = 0
currentRequest := sequence[r.currentIndex]
if hasPayloadIterator {
r.currentPayloads, r.okCurrentPayload = r.payloadIterator.Value()
if r.okCurrentPayload {
r.currentIndex++
return currentRequest, r.currentPayloads, true
}
}
}
}
return "", nil, false
}