Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/utils/http_probe.go
2838 views
1
package utils
2
3
import (
4
"fmt"
5
"net"
6
"net/http"
7
"strconv"
8
9
"github.com/projectdiscovery/httpx/common/httpx"
10
"github.com/projectdiscovery/nuclei/v3/pkg/input/types"
11
"github.com/projectdiscovery/useragent"
12
sliceutil "github.com/projectdiscovery/utils/slice"
13
)
14
15
var commonHttpPorts = []string{
16
"80",
17
"8080",
18
}
19
var defaultHttpSchemes = []string{
20
"https",
21
"http",
22
}
23
var httpFirstSchemes = []string{
24
"http",
25
"https",
26
}
27
28
// determineSchemeOrder for the input
29
func determineSchemeOrder(input string) []string {
30
if _, port, err := net.SplitHostPort(input); err == nil {
31
// if input has port that is commonly used for HTTP, return http then https
32
if sliceutil.Contains(commonHttpPorts, port) {
33
return httpFirstSchemes
34
}
35
36
// As of 10/2025 shodan shows that ports > 1024 are more likely to expose HTTP
37
// hence we test first http then https on higher ports
38
// if input has port > 1024, return http then https
39
if port, err := strconv.Atoi(port); err == nil && port > 1024 {
40
return httpFirstSchemes
41
}
42
}
43
44
return defaultHttpSchemes
45
}
46
47
// ProbeURL probes the scheme for a URL.
48
// http schemes are selected with heuristics
49
// If none succeeds, probing is abandoned for such URLs.
50
func ProbeURL(input string, httpxclient *httpx.HTTPX) string {
51
schemes := determineSchemeOrder(input)
52
for _, scheme := range schemes {
53
formedURL := fmt.Sprintf("%s://%s", scheme, input)
54
req, err := httpxclient.NewRequest(http.MethodHead, formedURL)
55
if err != nil {
56
continue
57
}
58
userAgent := useragent.PickRandom()
59
req.Header.Set("User-Agent", userAgent.Raw)
60
61
if _, err = httpxclient.Do(req, httpx.UnsafeOptions{}); err != nil {
62
continue
63
}
64
65
return formedURL
66
}
67
return ""
68
}
69
70
type inputLivenessChecker struct {
71
client *httpx.HTTPX
72
}
73
74
// ProbeURL probes the scheme for a URL.
75
func (i *inputLivenessChecker) ProbeURL(input string) (string, error) {
76
return ProbeURL(input, i.client), nil
77
}
78
79
func (i *inputLivenessChecker) Close() error {
80
if i.client.Dialer != nil {
81
i.client.Dialer.Close()
82
}
83
return nil
84
}
85
86
// GetInputLivenessChecker returns a new input liveness checker using provided httpx client
87
func GetInputLivenessChecker(client *httpx.HTTPX) types.InputLivenessProbe {
88
x := &inputLivenessChecker{client: client}
89
return x
90
}
91
92