Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/utils/utils.go
2843 views
1
package utils
2
3
import (
4
"context"
5
"errors"
6
"fmt"
7
"io"
8
"net/url"
9
"strings"
10
"time"
11
12
"github.com/cespare/xxhash"
13
"github.com/projectdiscovery/nuclei/v3/pkg/catalog"
14
"github.com/projectdiscovery/ratelimit"
15
"github.com/projectdiscovery/retryablehttp-go"
16
mapsutil "github.com/projectdiscovery/utils/maps"
17
"golang.org/x/exp/constraints"
18
)
19
20
func IsBlank(value string) bool {
21
return strings.TrimSpace(value) == ""
22
}
23
24
func UnwrapError(err error) error {
25
for { // get the last wrapped error
26
unwrapped := errors.Unwrap(err)
27
if unwrapped == nil {
28
break
29
}
30
err = unwrapped
31
}
32
return err
33
}
34
35
// IsURL tests a string to determine if it is a well-structured url or not.
36
func IsURL(input string) bool {
37
u, err := url.Parse(input)
38
return err == nil && u.Scheme != "" && u.Host != ""
39
}
40
41
// ReaderFromPathOrURL reads and returns the contents of a file or url.
42
func ReaderFromPathOrURL(templatePath string, catalog catalog.Catalog) (io.ReadCloser, error) {
43
if IsURL(templatePath) {
44
resp, err := retryablehttp.DefaultClient().Get(templatePath)
45
if err != nil {
46
return nil, err
47
}
48
return resp.Body, nil
49
} else {
50
f, err := catalog.OpenFile(templatePath)
51
if err != nil {
52
return nil, err
53
}
54
return f, nil
55
}
56
}
57
58
// StringSliceContains checks if a string slice contains a string.
59
func StringSliceContains(slice []string, item string) bool {
60
for _, i := range slice {
61
if strings.EqualFold(i, item) {
62
return true
63
}
64
}
65
return false
66
}
67
68
// MapHash generates a hash for any give map
69
func MapHash[K constraints.Ordered, V any](m map[K]V) uint64 {
70
keys := mapsutil.GetSortedKeys(m)
71
var sb strings.Builder
72
for _, k := range keys {
73
sb.WriteString(fmt.Sprintf("%v:%v\n", k, m[k]))
74
}
75
return xxhash.Sum64([]byte(sb.String()))
76
}
77
78
// GetRateLimiter returns a rate limiter with the given max tokens and duration
79
// if maxTokens is 0 or duration is 0, it returns an unlimited rate limiter
80
func GetRateLimiter(ctx context.Context, maxTokens int, duration time.Duration) *ratelimit.Limiter {
81
if maxTokens == 0 || duration == 0 {
82
return ratelimit.NewUnlimited(ctx)
83
}
84
return ratelimit.New(ctx, uint(maxTokens), duration)
85
}
86
87