Skip to content

Commit 603a86b

Browse files
authored
Merge pull request #6511 from matejsmycka/http-probing-optimizations
feat: http(s) probing optimization
2 parents 75016d1 + e0d3bb4 commit 603a86b

File tree

2 files changed

+69
-8
lines changed

2 files changed

+69
-8
lines changed

pkg/utils/http_probe.go

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,46 @@ package utils
22

33
import (
44
"fmt"
5+
"net"
56
"net/http"
67

78
"github.com/projectdiscovery/httpx/common/httpx"
89
"github.com/projectdiscovery/nuclei/v3/pkg/input/types"
910
"github.com/projectdiscovery/useragent"
11+
sliceutil "github.com/projectdiscovery/utils/slice"
1012
)
1113

12-
var (
13-
HttpSchemes = []string{"https", "http"}
14-
)
14+
var commonHttpPorts = []string{
15+
"80",
16+
"8080",
17+
}
18+
var defaultHttpSchemes = []string{
19+
"https",
20+
"http",
21+
}
22+
var httpFirstSchemes = []string{
23+
"http",
24+
"https",
25+
}
26+
27+
// determineSchemeOrder for the input
28+
func determineSchemeOrder(input string) []string {
29+
// if input has port that is commonly used for HTTP, return http then https
30+
if _, port, err := net.SplitHostPort(input); err == nil {
31+
if sliceutil.Contains(commonHttpPorts, port) {
32+
return httpFirstSchemes
33+
}
34+
}
35+
36+
return defaultHttpSchemes
37+
}
1538

16-
// ProbeURL probes the scheme for a URL. first HTTPS is tried
17-
// and if any errors occur http is tried. If none succeeds, probing
18-
// is abandoned for such URLs.
39+
// ProbeURL probes the scheme for a URL.
40+
// http schemes are selected with heuristics
41+
// If none succeeds, probing is abandoned for such URLs.
1942
func ProbeURL(input string, httpxclient *httpx.HTTPX) string {
20-
for _, scheme := range HttpSchemes {
43+
schemes := determineSchemeOrder(input)
44+
for _, scheme := range schemes {
2145
formedURL := fmt.Sprintf("%s://%s", scheme, input)
2246
req, err := httpxclient.NewRequest(http.MethodHead, formedURL)
2347
if err != nil {
@@ -39,7 +63,7 @@ type inputLivenessChecker struct {
3963
client *httpx.HTTPX
4064
}
4165

42-
// ProbeURL probes the scheme for a URL. first HTTPS is tried
66+
// ProbeURL probes the scheme for a URL.
4367
func (i *inputLivenessChecker) ProbeURL(input string) (string, error) {
4468
return ProbeURL(input, i.client), nil
4569
}

pkg/utils/http_probe_test.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package utils
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
)
8+
9+
func TestDetermineSchemeOrder(t *testing.T) {
10+
type testCase struct {
11+
input string
12+
expected []string
13+
}
14+
15+
tests := []testCase{
16+
// No port or uncommon ports should return https first
17+
{"example.com", []string{"https", "http"}},
18+
{"example.com:443", []string{"https", "http"}},
19+
{"127.0.0.1", []string{"https", "http"}},
20+
{"[fe80::1]:443", []string{"https", "http"}},
21+
// Common HTTP ports should return http first
22+
{"example.com:80", []string{"http", "https"}},
23+
{"example.com:8080", []string{"http", "https"}},
24+
{"127.0.0.1:80", []string{"http", "https"}},
25+
{"127.0.0.1:8080", []string{"http", "https"}},
26+
{"fe80::1", []string{"https", "http"}},
27+
{"[fe80::1]:80", []string{"http", "https"}},
28+
{"[fe80::1]:8080", []string{"http", "https"}},
29+
}
30+
31+
for _, tc := range tests {
32+
t.Run(tc.input, func(t *testing.T) {
33+
actual := determineSchemeOrder(tc.input)
34+
require.Equal(t, tc.expected, actual)
35+
})
36+
}
37+
}

0 commit comments

Comments
 (0)