@@ -10,6 +10,7 @@ import (
1010 "os"
1111 "sort"
1212 "sync"
13+ "time"
1314
1415 "github.com/CyberRoute/bruter/pkg/config"
1516 "github.com/CyberRoute/bruter/pkg/models"
@@ -35,11 +36,13 @@ func Dirsearch(Mu *sync.Mutex, app *config.AppConfig, domain, path string, progr
3536 url , err := NormalizeURL (urjoin )
3637 if err != nil {
3738 app .ZeroLog .Error ().Err (err ).Msgf ("Error parsing URL: %s" , urjoin )
39+ return
3840 }
3941
4042 head , err := http .NewRequest ("HEAD" , url , nil )
4143 if err != nil {
4244 app .ZeroLog .Error ().Err (err ).Msgf ("Error creating request for URL: %s" , url )
45+ return
4346 }
4447 head .Header .Set ("User-Agent" , GetRandomUserAgent ())
4548
@@ -53,11 +56,40 @@ func Dirsearch(Mu *sync.Mutex, app *config.AppConfig, domain, path string, progr
5356 return http .ErrUseLastResponse
5457 }}
5558
56- resp , err := client .Do (head )
57- if err != nil {
58- app .ZeroLog .Error ().Err (err ).Msgf ("Error performing request for URL: %s" , url )
59+ var resp * http.Response
60+
61+ // Exponential backoff parameters
62+ maxRetries := 5
63+ backoff := time .Second
64+
65+ for attempt := 1 ; attempt <= maxRetries ; attempt ++ {
66+ resp , err = client .Do (head )
67+ if err != nil {
68+ app .ZeroLog .Error ().Err (err ).Msgf ("Error performing request for URL: %s" , url )
69+ return
70+ }
71+
72+ if resp .StatusCode == 429 {
73+ retryAfter := resp .Header .Get ("Retry-After" )
74+ retryDelay , _ := time .ParseDuration (fmt .Sprintf ("%ss" , retryAfter ))
75+ if retryDelay == 0 {
76+ retryDelay = backoff
77+ }
78+ app .ZeroLog .Warn ().Msgf ("Rate limit exceeded. Retrying after %s" , retryDelay )
79+ time .Sleep (retryDelay )
80+ backoff *= 2
81+ continue
82+ } else {
83+ break
84+ }
5985 }
60- if resp != nil && resp .StatusCode == http .StatusMovedPermanently || resp .StatusCode == http .StatusFound { //status codes 301 302
86+
87+ if resp == nil {
88+ app .ZeroLog .Error ().Msg ("Failed to get a valid response" )
89+ return
90+ }
91+
92+ if resp .StatusCode == http .StatusMovedPermanently || resp .StatusCode == http .StatusFound { //status codes 301 302
6193 // Add the RedirectPath field to the payload
6294 redirectPath := resp .Header .Get ("Location" )
6395 payload := & models.Url {Path : url , Progress : progress , Status : float64 (resp .StatusCode ), RedirectPath : redirectPath }
0 commit comments