| skipped 4 lines |
5 | 5 | | "fmt" |
6 | 6 | | "net/http" |
7 | 7 | | "os" |
| 8 | + | "regexp" |
| 9 | + | "strings" |
8 | 10 | | "sync" |
9 | 11 | | |
10 | 12 | | "github.com/edoardottt/csprecon/pkg/input" |
| 13 | + | "github.com/edoardottt/csprecon/pkg/output" |
11 | 14 | | "github.com/edoardottt/golazy" |
12 | 15 | | "github.com/projectdiscovery/gologger" |
13 | 16 | | fileutil "github.com/projectdiscovery/utils/file" |
| skipped 3 lines |
17 | 20 | | Client *http.Client |
18 | 21 | | Input chan string |
19 | 22 | | Output chan string |
20 | | - | InWg sync.WaitGroup |
21 | | - | OutWg sync.WaitGroup |
| 23 | + | InWg *sync.WaitGroup |
| 24 | + | OutWg *sync.WaitGroup |
22 | 25 | | Options input.Options |
23 | 26 | | } |
24 | 27 | | |
25 | 28 | | func New(options *input.Options) Runner { |
26 | 29 | | return Runner{ |
27 | 30 | | Client: customClient(options.Timeout), |
28 | | - | Input: make(chan string), |
29 | | - | Output: make(chan string), |
30 | | - | InWg: sync.WaitGroup{}, |
31 | | - | OutWg: sync.WaitGroup{}, |
| 31 | + | Input: make(chan string, options.Concurrency), |
| 32 | + | Output: make(chan string, options.Concurrency), |
| 33 | + | InWg: &sync.WaitGroup{}, |
| 34 | + | OutWg: &sync.WaitGroup{}, |
32 | 35 | | Options: *options, |
33 | 36 | | } |
34 | 37 | | } |
| skipped 40 lines |
75 | 78 | | func execute(r *Runner) { |
76 | 79 | | defer r.InWg.Done() |
77 | 80 | | |
| 81 | + | regex := regexp.Regexp{} |
| 82 | + | |
| 83 | + | if r.Options.Domain != "" { |
| 84 | + | regex = *CompileRegex(`.*` + r.Options.Domain) |
| 85 | + | } |
| 86 | + | |
| 87 | + | dregex := CompileRegex(DomainRegex) |
| 88 | + | |
78 | 89 | | for value := range r.Input { |
79 | | - | result, err := checkCSP(value, r.Client) |
80 | | - | if err == nil { |
81 | | - | for _, res := range result { |
82 | | - | r.Output <- res |
| 90 | + | r.InWg.Add(1) |
| 91 | + | |
| 92 | + | go func(value string) { |
| 93 | + | defer r.InWg.Done() |
| 94 | + | result, err := checkCSP(value, dregex, r.Client) |
| 95 | + | |
| 96 | + | if err == nil { |
| 97 | + | for _, res := range result { |
| 98 | + | if resTrimmed := strings.TrimSpace(res); resTrimmed != "" { |
| 99 | + | if r.Options.Domain != "" { |
| 100 | + | if regex.Match([]byte(resTrimmed)) { |
| 101 | + | r.Output <- resTrimmed |
| 102 | + | } |
| 103 | + | } else { |
| 104 | + | r.Output <- resTrimmed |
| 105 | + | } |
| 106 | + | } |
| 107 | + | } |
83 | 108 | | } |
84 | | - | } |
| 109 | + | }(value) |
85 | 110 | | } |
86 | 111 | | } |
87 | 112 | | |
88 | 113 | | func pullOutput(r *Runner) { |
89 | 114 | | defer r.OutWg.Done() |
90 | 115 | | |
| 116 | + | out := output.New() |
| 117 | + | |
91 | 118 | | for o := range r.Output { |
92 | 119 | | r.OutWg.Add(1) |
93 | 120 | | |
94 | | - | go writeOutput(&r.OutWg, &r.Options, o) |
| 121 | + | go writeOutput(r.OutWg, &r.Options, &out, o) |
95 | 122 | | } |
96 | 123 | | } |
97 | 124 | | |
98 | | - | func writeOutput(wg *sync.WaitGroup, options *input.Options, out string) { |
| 125 | + | func writeOutput(wg *sync.WaitGroup, options *input.Options, out *output.Result, o string) { |
99 | 126 | | defer wg.Done() |
100 | 127 | | |
101 | 128 | | if options.FileOutput != "" { |
| skipped 5 lines |
107 | 134 | | options.Output = file |
108 | 135 | | } |
109 | 136 | | |
110 | | - | // write output to file |
| 137 | + | if !out.Printed(o) { |
| 138 | + | if options.Output != nil { |
| 139 | + | if _, err := options.Output.Write([]byte(o + "\n")); err != nil && options.Verbose { |
| 140 | + | gologger.Fatal().Msg(err.Error()) |
| 141 | + | } |
| 142 | + | } |
111 | 143 | | |
112 | | - | fmt.Println(out) |
| 144 | + | fmt.Println(o) |
| 145 | + | } |
113 | 146 | | } |
114 | 147 | | |