Initial progress bar implementation

dev
Manuel Bua 2020-07-04 23:00:11 +02:00
parent 48b63c4edd
commit 6d68b09863
8 changed files with 259 additions and 96 deletions

19
go.mod
View File

@ -1,22 +1,3 @@
module github.com/projectdiscovery/nuclei
go 1.14
require (
github.com/Knetic/govaluate v3.0.0+incompatible
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535
github.com/blang/semver v3.5.1+incompatible
github.com/d5/tengo v1.24.8
github.com/d5/tengo/v2 v2.6.0
github.com/google/go-github v17.0.0+incompatible
github.com/google/go-github/v32 v32.0.0
github.com/json-iterator/go v1.1.10
github.com/karrick/godirwalk v1.15.6
github.com/miekg/dns v1.1.29
github.com/pkg/errors v0.9.1
github.com/projectdiscovery/gologger v1.0.0
github.com/projectdiscovery/retryabledns v1.0.4
github.com/projectdiscovery/retryablehttp-go v1.0.1
golang.org/x/net v0.0.0-20200528225125-3c3fba18258b
gopkg.in/yaml.v2 v2.3.0
)

71
go.sum
View File

@ -1,71 +0,0 @@
github.com/Knetic/govaluate v1.5.0 h1:L4MyqdJSld9xr2eZcZHCWLfeIX2SBjqrwIKG1pcm/+4=
github.com/Knetic/govaluate v3.0.0+incompatible h1:7o6+MAPhYTCF0+fdvoz1xDedhRb4f6s9Tn1Tt7/WTEg=
github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY=
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
github.com/blang/semver v1.1.0 h1:ol1rO7QQB5uy7umSNV7VAmLugfLRD+17sYJujRNYPhg=
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/d5/tengo v1.24.8 h1:PRJ+NWt7ae/9sSbIfThOBTkPSvNV+dwYoBAvwfNgNJY=
github.com/d5/tengo v1.24.8/go.mod h1:VhLq8Q2QFhCIJO3NhvM934qOThykMqJi9y9Siqd1ocQ=
github.com/d5/tengo/v2 v2.6.0 h1:D0cJtpiBzaLJ/Smv6nnUc/LIfO46oKwDx85NZtIRNRI=
github.com/d5/tengo/v2 v2.6.0/go.mod h1:XRGjEs5I9jYIKTxly6HCF8oiiilk5E/RYXOZ5b0DZC8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-github/v32 v32.0.0 h1:q74KVb22spUq0U5HqZ9VCYqQz8YRuOtL/39ZnfwO+NM=
github.com/google/go-github/v32 v32.0.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/karrick/godirwalk v1.15.6 h1:Yf2mmR8TJy+8Fa0SuQVto5SYap6IF7lNVX4Jdl8G1qA=
github.com/karrick/godirwalk v1.15.6/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381 h1:bqDmpDG49ZRnB5PcgP0RXtQvnMSgIF14M7CBd2shtXs=
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/miekg/dns v1.1.29 h1:xHBEhR+t5RzcFJjBLJlax2daXOrTYtr9z4WdKEfWFzg=
github.com/miekg/dns v1.1.29/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/projectdiscovery/gologger v1.0.0 h1:XAQ8kHeVKXMjY4rLGh7eT5+oHU077BNEvs7X6n+vu1s=
github.com/projectdiscovery/gologger v1.0.0/go.mod h1:Ok+axMqK53bWNwDSU1nTNwITLYMXMdZtRc8/y1c7sWE=
github.com/projectdiscovery/retryabledns v1.0.4 h1:0Va7qHlWQsIXjRLISTjzfN3tnJmHYDudY05Nu3IJd60=
github.com/projectdiscovery/retryabledns v1.0.4/go.mod h1:/UzJn4I+cPdQl6pKiiQfvVAT636YZvJQYZhYhGB0dUQ=
github.com/projectdiscovery/retryablehttp-go v1.0.1 h1:V7wUvsZNq1Rcz7+IlcyoyQlNwshuwptuBVYWw9lx8RE=
github.com/projectdiscovery/retryablehttp-go v1.0.1/go.mod h1:SrN6iLZilNG1X4neq1D+SBxoqfAF4nyzvmevkTkWsek=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200528225125-3c3fba18258b h1:IYiJPiJfzktmDAO1HQiwjMjwjlYKHAL7KzeD544RJPs=
golang.org/x/net v0.0.0-20200528225125-3c3fba18258b/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@ -6,17 +6,18 @@ require (
github.com/Knetic/govaluate v3.0.0+incompatible
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535
github.com/blang/semver v3.5.1+incompatible
github.com/d5/tengo v1.24.8
github.com/d5/tengo/v2 v2.6.0
github.com/google/go-github v17.0.0+incompatible
github.com/google/go-github/v32 v32.0.0
github.com/json-iterator/go v1.1.10
github.com/karrick/godirwalk v1.15.6
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381
github.com/miekg/dns v1.1.29
github.com/pkg/errors v0.9.1
github.com/projectdiscovery/gologger v1.0.0
github.com/projectdiscovery/retryabledns v1.0.4
github.com/projectdiscovery/retryablehttp-go v1.0.1
github.com/stretchr/testify v1.5.1
github.com/vbauerster/mpb/v5 v5.2.2
golang.org/x/net v0.0.0-20200528225125-3c3fba18258b
gopkg.in/yaml.v2 v2.3.0
)

View File

@ -0,0 +1,86 @@
package progress
import (
"fmt"
"github.com/logrusorgru/aurora"
"github.com/vbauerster/mpb/v5"
"github.com/vbauerster/mpb/v5/cwriter"
"github.com/vbauerster/mpb/v5/decor"
"io"
"os"
"regexp"
"strconv"
"strings"
"sync"
)
type Progress struct {
progress *mpb.Progress
captureData *captureData
termWidth int
}
func NewProgress(group *sync.WaitGroup) *Progress {
w := cwriter.New(os.Stdout)
tw, err := w.GetWidth()
if err != nil {
panic("Couldn't determine available terminal width.")
}
p := &Progress{
progress: mpb.New(
mpb.WithWaitGroup(group),
mpb.WithOutput(os.Stderr),
mpb.PopCompletedMode(),
),
termWidth: tw,
}
return p
}
func (p *Progress) NewBar(name string, total int64, URL string) *mpb.Bar {
return p.progress.AddBar(
total,
mpb.BarNoPop(),
mpb.PrependDecorators(
decor.Name("[" + aurora.Green(URL).String() + " / " + aurora.Magenta(name).String() + "]"),
decor.CountersNoUnit(aurora.Blue(" %d/%d").String()),
decor.NewPercentage(aurora.Bold("%d").String(), decor.WCSyncSpace),
),
mpb.AppendDecorators(
decor.EwmaSpeed(0, aurora.Yellow("%.2f req/s ").String(), 60),
decor.OnComplete(
decor.EwmaETA(decor.ET_STYLE_GO, 60), aurora.Bold("done!").String(),
),
),
)
}
func (p *Progress) Wait() {
p.progress.Wait()
}
//
func (p *Progress) StartStdCapture() {
p.captureData = startStdCapture()
}
func (p *Progress) StopStdCaptureAndShow() {
stopStdCapture(p.captureData)
for _, captured := range p.captureData.Data {
var r = regexp.MustCompile("(.{" + strconv.Itoa(p.termWidth) + "})")
multiline := r.ReplaceAllString(captured, "$1\n")
arr := strings.Split(multiline, "\n")
for _, msg := range arr {
p.progress.Add(0, makeLogBar(msg)).SetTotal(0, true)
}
}
}
func makeLogBar(msg string) mpb.BarFiller {
return mpb.BarFillerFunc(func(w io.Writer, _ int, st decor.Statistics) {
fmt.Fprintf(w, msg)
})
}

View File

@ -0,0 +1,112 @@
package progress
/**
Inspired by the https://github.com/PumpkinSeed/cage module
*/
import (
"bytes"
"context"
"io"
"os"
"strings"
"sync"
"time"
)
type captureData struct {
backupStdout *os.File
writerStdout *os.File
backupStderr *os.File
writerStderr *os.File
data string
channel chan string
sync sync.WaitGroup
Data []string
}
var(
mutex = &sync.Mutex{}
)
func startStdCapture() *captureData {
mutex.Lock()
rStdout, wStdout, errStdout := os.Pipe()
if errStdout != nil {
panic(errStdout)
}
rStderr, wStderr, errStderr := os.Pipe()
if errStderr != nil {
panic(errStderr)
}
c := &captureData{
backupStdout: os.Stdout,
writerStdout: wStdout,
backupStderr: os.Stderr,
writerStderr: wStderr,
channel: make(chan string),
}
os.Stdout = c.writerStdout
os.Stderr = c.writerStderr
c.sync.Add(2)
go func( wg *sync.WaitGroup, out chan string, readerStdout *os.File, readerStderr *os.File) {
defer wg.Done()
var bufStdout bytes.Buffer
_, _ = io.Copy(&bufStdout, readerStdout)
if bufStdout.Len() > 0 {
out <- bufStdout.String()
}
var bufStderr bytes.Buffer
_, _ = io.Copy(&bufStderr, readerStderr)
if bufStderr.Len() > 0 {
out <- bufStderr.String()
}
}(&c.sync, c.channel, rStdout, rStderr)
ctx, _ := context.WithTimeout(context.Background(), 50 * time.Millisecond)
//defer cancel()
go func(ctx context.Context, wg *sync.WaitGroup, c *captureData) {
defer wg.Done()
select {
case out := <-c.channel:
c.data += out
case <-ctx.Done():
break
}
}(ctx, &c.sync, c)
return c
}
func stopStdCapture(c *captureData) {
_ = c.writerStdout.Close()
_ = c.writerStderr.Close()
c.sync.Wait()
close(c.channel)
os.Stdout = c.backupStdout
os.Stderr = c.backupStderr
c.Data = strings.Split(c.data, "\n")
if c.Data[len(c.Data)-1] == "" {
c.Data = c.Data[:len(c.Data)-1]
}
mutex.Unlock()
}

View File

@ -5,6 +5,7 @@ import (
"context"
"errors"
"fmt"
"github.com/projectdiscovery/nuclei/v2/internal/progress"
"io"
"io/ioutil"
"os"
@ -268,6 +269,9 @@ func (r *Runner) processTemplateWithList(template *templates.Template, request i
limiter := make(chan struct{}, r.options.Threads)
wg := &sync.WaitGroup{}
// track progress
p := progress.NewProgress(wg)
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
text := scanner.Text()
@ -281,20 +285,24 @@ func (r *Runner) processTemplateWithList(template *templates.Template, request i
var err error
if httpExecutor != nil {
err = httpExecutor.ExecuteHTTP(URL)
err = httpExecutor.ExecuteHTTP(p, URL)
}
if dnsExecutor != nil {
err = dnsExecutor.ExecuteDNS(URL)
}
if err != nil {
p.StartStdCapture()
gologger.Warningf("Could not execute step: %s\n", err)
p.StopStdCaptureAndShow()
}
<-limiter
wg.Done()
}(text)
}
close(limiter)
wg.Wait()
// Wait for both the WaitGroup and all the bars to complete
p.Wait()
// See if we got any results from the executors
var results bool

View File

@ -4,6 +4,7 @@ import (
"bufio"
"crypto/tls"
"fmt"
"github.com/projectdiscovery/nuclei/v2/internal/progress"
"io"
"io/ioutil"
"net/http"
@ -92,30 +93,46 @@ func (e *HTTPExecutor) GotResults() bool {
return true
}
func (e *HTTPExecutor) GetRequestCount() int64 {
return int64( len(e.httpRequest.Raw) | len(e.httpRequest.Path) )
}
// ExecuteHTTP executes the HTTP request on a URL
func (e *HTTPExecutor) ExecuteHTTP(URL string) error {
func (e *HTTPExecutor) ExecuteHTTP(p *progress.Progress, URL string) error {
// Compile each request for the template based on the URL
compiledRequest, err := e.httpRequest.MakeHTTPRequest(URL)
if err != nil {
return errors.Wrap(err, "could not make http request")
}
// track progress
bar := p.NewBar(e.template.ID, e.GetRequestCount(), URL)
// Send the request to the target servers
mainLoop:
for compiledRequest := range compiledRequest {
start := time.Now()
if compiledRequest.Error != nil {
bar.Abort(true)
return errors.Wrap(err, "could not make http request")
}
e.setCustomHeaders(compiledRequest)
req := compiledRequest.Request
if e.debug {
p.StartStdCapture()
gologger.Infof("Dumped HTTP request for %s (%s)\n\n", URL, e.template.ID)
p.StopStdCaptureAndShow()
dumpedRequest, err := httputil.DumpRequest(req.Request, true)
if err != nil {
bar.Abort(true)
return errors.Wrap(err, "could not dump http request")
}
p.StartStdCapture()
fmt.Fprintf(os.Stderr, "%s", string(dumpedRequest))
p.StopStdCaptureAndShow()
}
resp, err := e.httpClient.Do(req)
@ -123,22 +140,30 @@ mainLoop:
if resp != nil {
resp.Body.Close()
}
bar.Abort(true)
return errors.Wrap(err, "could not make http request")
}
if e.debug {
p.StartStdCapture()
gologger.Infof("Dumped HTTP response for %s (%s)\n\n", URL, e.template.ID)
p.StopStdCaptureAndShow()
dumpedResponse, err := httputil.DumpResponse(resp, true)
if err != nil {
bar.Abort(true)
return errors.Wrap(err, "could not dump http response")
}
p.StartStdCapture()
fmt.Fprintf(os.Stderr, "%s\n", string(dumpedResponse))
p.StopStdCaptureAndShow()
}
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
io.Copy(ioutil.Discard, resp.Body)
resp.Body.Close()
bar.Abort(true)
return errors.Wrap(err, "could not read http body")
}
resp.Body.Close()
@ -147,6 +172,7 @@ mainLoop:
// so in case we have to manually do it
data, err = requests.HandleDecompression(compiledRequest.Request, data)
if err != nil {
bar.Abort(true)
return errors.Wrap(err, "could not decompress http body")
}
@ -166,13 +192,19 @@ mainLoop:
if !matcher.Match(resp, body, headers) {
// If the condition is AND we haven't matched, try next request.
if matcherCondition == matchers.ANDCondition {
bar.IncrBy(1)
bar.DecoratorEwmaUpdate(time.Since(start))
continue mainLoop
}
} else {
// If the matcher has matched, and its an OR
// write the first output then move to next matcher.
if matcherCondition == matchers.ORCondition && len(e.httpRequest.Extractors) == 0 {
// capture stdout and emit it via a mpb.BarFiller
p.StartStdCapture()
e.writeOutputHTTP(compiledRequest, matcher, nil)
p.StopStdCaptureAndShow()
atomic.CompareAndSwapUint32(&e.results, 0, 1)
}
}
@ -194,16 +226,26 @@ mainLoop:
// Write a final string of output if matcher type is
// AND or if we have extractors for the mechanism too.
if len(e.httpRequest.Extractors) > 0 || matcherCondition == matchers.ANDCondition {
// capture stdout and emit it via a mpb.BarFiller
p.StartStdCapture()
e.writeOutputHTTP(compiledRequest, nil, extractorResults)
p.StopStdCaptureAndShow()
atomic.CompareAndSwapUint32(&e.results, 0, 1)
}
bar.Increment()
bar.DecoratorEwmaUpdate(time.Since(start))
}
p.StartStdCapture()
gologger.Verbosef("Sent HTTP request to %s\n", "http-request", URL)
p.StopStdCaptureAndShow()
return nil
}
// Close closes the http executor for a template.
func (e *HTTPExecutor) Close() {
e.outputMutex.Lock()

View File

@ -3,6 +3,7 @@ package workflows
import (
"github.com/d5/tengo/v2"
"github.com/projectdiscovery/gologger"
"github.com/projectdiscovery/nuclei/v2/internal/progress"
"github.com/projectdiscovery/nuclei/v2/pkg/executor"
)
@ -33,6 +34,9 @@ func (n *NucleiVar) CanCall() bool {
func (n *NucleiVar) Call(args ...tengo.Object) (ret tengo.Object, err error) {
var gotResult bool
// track progress
p := progress.NewProgress(nil)
for _, template := range n.Templates {
if template.HTTPOptions != nil {
for _, request := range template.HTTPOptions.Template.RequestsHTTP {
@ -42,7 +46,7 @@ func (n *NucleiVar) Call(args ...tengo.Object) (ret tengo.Object, err error) {
gologger.Warningf("Could not compile request for template '%s': %s\n", template.HTTPOptions.Template.ID, err)
continue
}
err = httpExecutor.ExecuteHTTP(n.URL)
err = httpExecutor.ExecuteHTTP(p, n.URL)
if err != nil {
gologger.Warningf("Could not send request for template '%s': %s\n", template.HTTPOptions.Template.ID, err)
continue