Skip to content

Commit 0840905

Browse files
authored
Merge pull request #2308 from projectdiscovery/dev
v1.7.2
2 parents 016f983 + d370e9e commit 0840905

File tree

25 files changed

+674
-232
lines changed

25 files changed

+674
-232
lines changed

.github/auto_assign.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
addReviewers: true
2+
reviewers:
3+
- dogancanbakir
4+
- dwisiswant0
5+
- mzack9999
6+
7+
numberOfReviewers: 1
8+
skipKeywords:
9+
- '@dependabot'

.github/workflows/stale.yaml

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,41 @@
1-
name: 'Close stale issues and PR'
1+
name: 💤 Stale
2+
23
on:
34
schedule:
4-
- cron: '30 1 * * *'
5+
- cron: "0 0 * * 0" # Weekly
56

67
jobs:
78
stale:
89
runs-on: ubuntu-latest
10+
permissions:
11+
actions: write
12+
contents: write # only for delete-branch option
13+
issues: write
14+
pull-requests: write
915
steps:
1016
- uses: actions/stale@v9
1117
with:
12-
only-labels: "Status: Abandoned, Type: Question"
13-
stale-issue-label: stale
14-
stale-issue-message: 'This issue is stale because it has been open 14 days with no activity. Remove stale label or comment or this will be closed in 90 days.'
15-
close-issue-message: 'This issue was closed because it has been stalled for 90 days with no activity.'
16-
days-before-stale: 14
17-
days-before-close: 90
18-
days-before-pr-stale: -1
19-
days-before-pr-close: -1
20-
stale-pr-message: ''
21-
close-pr-message: ''
18+
days-before-stale: 90
19+
days-before-close: 7
20+
stale-issue-label: "Status: Stale"
21+
stale-pr-label: "Status: Stale"
22+
stale-issue-message: >
23+
This issue has been automatically marked as stale because it has not
24+
had recent activity. It will be closed in 7 days if no further
25+
activity occurs. Thank you for your contributions!
26+
stale-pr-message: >
27+
This pull request has been automatically marked as stale due to
28+
inactivity. It will be closed in 7 days if no further activity
29+
occurs. Please update if you wish to keep it open.
30+
close-issue-message: >
31+
This issue has been automatically closed due to inactivity. If you
32+
think this is a mistake or would like to continue the discussion,
33+
please comment or feel free to reopen it.
34+
close-pr-message: >
35+
This pull request has been automatically closed due to inactivity.
36+
If you think this is a mistake or would like to continue working on
37+
it, please comment or feel free to reopen it.
38+
close-issue-label: "Status: Abandoned"
39+
close-pr-label: "Status: Abandoned"
40+
exempt-issue-labels: "Status: Abandoned"
41+
exempt-pr-labels: "Status: Abandoned"

.goreleaser.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ builds:
2727
main: cmd/httpx/httpx.go
2828

2929
archives:
30-
- format: zip
30+
- formats:
31+
- zip
3132
name_template: '{{ .ProjectName }}_{{ .Version }}_{{ if eq .Os "darwin" }}macOS{{ else }}{{ .Os }}{{ end }}_{{ .Arch }}'
3233

3334
checksum:
@@ -42,4 +43,4 @@ announce:
4243

4344
discord:
4445
enabled: true
45-
message_template: '**New Release: {{ .ProjectName }} {{.Tag}}** is published! Check it out at {{ .ReleaseURL }}'
46+
message_template: '**New Release: {{ .ProjectName }} {{.Tag}}** is published! Check it out at {{ .ReleaseURL }}'

README.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262

6363
# Installation Instructions
6464

65-
`httpx` requires **go1.21** to install successfully. Run the following command to get the repo:
65+
`httpx` requires **go >=1.24.0** to install successfully. Run the following command to get the repo:
6666

6767
```sh
6868
go install -v github.com/projectdiscovery/httpx/cmd/httpx@latest
@@ -85,10 +85,6 @@ This will display help for the tool. Here are all the switches it supports.
8585

8686

8787
```console
88-
Usage:
89-
./httpx [flags]
90-
91-
Flags:
9288
httpx is a fast and multi-purpose HTTP toolkit that allows running multiple probes using the retryablehttp library.
9389

9490
Usage:
@@ -115,8 +111,9 @@ PROBES:
115111
-bp, -body-preview display first N characters of response body (default 100)
116112
-server, -web-server display server name
117113
-td, -tech-detect display technology in use based on wappalyzer dataset
114+
-cff, -custom-fingerprint-file string path to a custom fingerprint file for technology detection
118115
-method display http request method
119-
-websocket display server using websocket
116+
-ws, -websocket display server using websocket
120117
-ip display host ip
121118
-cname display host cname
122119
-extract-fqdn, -efqdn get domain and subdomains from response body and header in jsonl/csv output
@@ -133,6 +130,7 @@ HEADLESS:
133130
-ehb, -exclude-headless-body enable excluding headless header from json output
134131
-st, -screenshot-timeout value set timeout for screenshot in seconds (default 10s)
135132
-sid, -screenshot-idle value set idle time before taking screenshot in seconds (default 1s)
133+
-jsc, -javascript-code string[] execute JavaScript code after navigation
136134

137135
MATCHERS:
138136
-mc, -match-code string match response with specified status code (-mc 200,302)
@@ -203,6 +201,8 @@ OUTPUT:
203201
-svrc, -store-vision-recon-cluster include visual recon clusters (-ss and -sr only)
204202
-pr, -protocol string protocol to use (unknown, http11)
205203
-fepp, -filter-error-page-path string path to store filtered error pages (default "filtered_error_page.json")
204+
-lof, -list-output-fields list available output field names for filtering
205+
-eof, -exclude-output-fields string[] exclude specified output fields from results
206206

207207
CONFIGURATIONS:
208208
-config string path to the httpx configuration file (default $HOME/.config/httpx/config.yaml)
@@ -211,6 +211,7 @@ CONFIGURATIONS:
211211
-deny string[] denied list of IP/CIDR's to process (file or comma separated)
212212
-sni, -sni-name string custom TLS SNI name
213213
-random-agent enable Random User-Agent to use (default true)
214+
-auto-referer set the Referer header to the current URL (default false)
214215
-H, -header string[] custom http headers to send with request
215216
-http-proxy, -proxy string http proxy to use (eg http://127.0.0.1:8080)
216217
-unsafe send raw requests skipping golang normalization

cmd/functional-test/main.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ func runFunctionalTests() error {
4141
if err != nil {
4242
return errors.Wrap(err, "could not open test cases")
4343
}
44-
defer file.Close()
44+
defer func() {
45+
_ = file.Close()
46+
}()
4547

4648
scanner := bufio.NewScanner(file)
4749
for scanner.Scan() {

cmd/httpx/httpx.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,6 @@ func setupOptionalAssetUpload(opts *runner.Options) *pdcp.UploadWriter {
106106
}
107107
return nil
108108
}
109-
if opts.Screenshot {
110-
gologger.Fatal().Msgf("Screenshot option is not supported for dashboard upload yet")
111-
}
112109
gologger.Info().Msgf("To view results in UI dashboard, visit https://cloud.projectdiscovery.io/assets upon completion.")
113110
h := &pdcpauth.PDCPCredHandler{}
114111
creds, err := h.GetCreds()
@@ -131,10 +128,11 @@ func setupOptionalAssetUpload(opts *runner.Options) *pdcp.UploadWriter {
131128
opts.OnClose = func() {
132129
writer.Close()
133130
}
131+
134132
// add additional metadata
135133
if opts.AssetID != "" {
136134
// silently ignore
137-
_ = writer.SetAssetID(opts.AssetID)
135+
writer.SetAssetID(opts.AssetID)
138136
}
139137
if opts.AssetName != "" {
140138
// silently ignore

cmd/integration-test/http.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ type standardHttpGet struct {
4949
func (h *standardHttpGet) Execute() error {
5050
router := httprouter.New()
5151
router.GET("/", httprouter.Handle(func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
52-
fmt.Fprintf(w, "This is a test")
52+
_, _ = fmt.Fprintf(w, "This is a test")
5353
r.Close = true
5454
}))
5555
var ts *httptest.Server
@@ -100,7 +100,7 @@ func (h *issue276) Execute() error {
100100
router.GET("/redirect", httprouter.Handle(func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
101101
w.Header().Add("Location", ts.URL+"/redirect")
102102
w.WriteHeader(302)
103-
fmt.Fprintf(w, "<html><body><title>Object moved</title></body></html>")
103+
_, _ = fmt.Fprintf(w, "<html><body><title>Object moved</title></body></html>")
104104
}))
105105
ts = httptest.NewServer(router)
106106
defer ts.Close()
@@ -163,7 +163,7 @@ func (h *issue303) Execute() error {
163163
// mimic a misconfigured web server behavior declaring gzip body
164164
w.Header().Add("Content-Encoding", "gzip")
165165
// but sending it uncompressed
166-
fmt.Fprint(w, "<html><body>This is a test</body></html>")
166+
_, _ = fmt.Fprint(w, "<html><body>This is a test</body></html>")
167167
}))
168168
ts = httptest.NewServer(router)
169169
defer ts.Close()
@@ -191,7 +191,7 @@ func (h *issue363) Execute() error {
191191
router.GET("/redirect", httprouter.Handle(func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
192192
w.Header().Add("Location", ts.URL+"/redirect")
193193
w.WriteHeader(302)
194-
fmt.Fprintf(w, "<html><body><title>Object moved</title></body></html>")
194+
_, _ = fmt.Fprintf(w, "<html><body><title>Object moved</title></body></html>")
195195
}))
196196
ts = httptest.NewServer(router)
197197
defer ts.Close()
@@ -214,7 +214,7 @@ func (h *issue400) Execute() error {
214214
router.POST("/receive", httprouter.Handle(func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
215215
w.Header().Add("Content-Type", "application/json")
216216
data, _ := io.ReadAll(r.Body)
217-
fmt.Fprintf(w, "data received %s", data)
217+
_, _ = fmt.Fprintf(w, "data received %s", data)
218218
}))
219219
ts = httptest.NewServer(router)
220220
defer ts.Close()
@@ -238,7 +238,7 @@ func (h *issue414) Execute() error {
238238
router.POST(uripath, httprouter.Handle(func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
239239
w.Header().Add("Content-Type", "application/json")
240240
data, _ := io.ReadAll(r.Body)
241-
fmt.Fprintf(w, "data received %s", data)
241+
_, _ = fmt.Fprintf(w, "data received %s", data)
242242
}))
243243
ts = httptest.NewServer(router)
244244
defer ts.Close()
@@ -265,7 +265,7 @@ func (h *titleUnwantedChars) Execute() error {
265265
uriPath := "/index"
266266
router.GET(uriPath, httprouter.Handle(func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
267267
htmlResponse := "<html><head><title>\v\fProject\n\r Discovery\n - Httpx\t></title></head><body>test data</body></html>"
268-
fmt.Fprint(w, htmlResponse)
268+
_, _ = fmt.Fprint(w, htmlResponse)
269269
}))
270270
ts = httptest.NewServer(router)
271271
defer ts.Close()
@@ -290,7 +290,7 @@ func (h *issue480) Execute() error {
290290
uriPath := "////////////////../../../../../../../../etc/passwd"
291291
router.GET(uriPath, httprouter.Handle(func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
292292
htmlResponse := "<html><body>ok from uri</body></html>"
293-
fmt.Fprint(w, htmlResponse)
293+
_, _ = fmt.Fprint(w, htmlResponse)
294294
}))
295295
ts = httptest.NewServer(router)
296296
defer ts.Close()
@@ -314,7 +314,7 @@ func (h *customHeader) Execute() error {
314314
router := httprouter.New()
315315
router.GET("/", httprouter.Handle(func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
316316
w.Header().Add("Content-Type", "application/json")
317-
fmt.Fprint(w, `{"status": "ok"}`)
317+
_, _ = fmt.Fprint(w, `{"status": "ok"}`)
318318
}))
319319
ts = httptest.NewServer(router)
320320
defer ts.Close()
@@ -341,7 +341,7 @@ func (h *outputMatchCondition) Execute() error {
341341
router.GET("/", httprouter.Handle(func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
342342
w.Header().Add("Content-Type", "application/json")
343343
w.WriteHeader(200)
344-
fmt.Fprint(w, `{"status": "ok"}`)
344+
_, _ = fmt.Fprint(w, `{"status": "ok"}`)
345345
}))
346346
ts = httptest.NewServer(router)
347347
defer ts.Close()
@@ -365,7 +365,7 @@ func (h *outputFilterCondition) Execute() error {
365365
router.GET("/", httprouter.Handle(func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
366366
w.Header().Add("Content-Type", "application/json")
367367
w.WriteHeader(200)
368-
fmt.Fprint(w, `{"status": "ok"}`)
368+
_, _ = fmt.Fprint(w, `{"status": "ok"}`)
369369
}))
370370
ts = httptest.NewServer(router)
371371
defer ts.Close()
@@ -390,7 +390,7 @@ func (h *outputAll) Execute() error {
390390
router.GET("/", httprouter.Handle(func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
391391
w.Header().Add("Content-Type", "application/json")
392392
w.WriteHeader(200)
393-
fmt.Fprint(w, `{"status": "ok"}`)
393+
_, _ = fmt.Fprint(w, `{"status": "ok"}`)
394394
}))
395395
ts = httptest.NewServer(router)
396396
defer ts.Close()

cmd/integration-test/library.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ func (h *httpxLibrary) Execute() error {
2222
if err != nil {
2323
return err
2424
}
25-
defer os.RemoveAll(testFile)
25+
defer func() {
26+
_ = os.RemoveAll(testFile)
27+
}()
2628

2729
var got string
2830

@@ -64,7 +66,9 @@ func (h *httpxLibraryWithStream) Execute() error {
6466
if err != nil {
6567
return err
6668
}
67-
defer os.RemoveAll(testFile)
69+
defer func() {
70+
_ = os.RemoveAll(testFile)
71+
}()
6872

6973
var got string
7074

common/customports/customport.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,14 @@ func (c *CustomPorts) Set(value string) error {
7777
}
7878
highP, err := strconv.Atoi(potentialRange[1])
7979
if err != nil {
80-
return errors.Wrap(err, fmt.Sprintf("Could not cast last port of your port range(%s) to integer from your value: %s", potentialPort, potentialRange[1]))
80+
return errors.Wrap(err, fmt.Sprintf("could not cast last port of your port range(%s) to integer from your value: %s", potentialPort, potentialRange[1]))
8181
}
8282
if err := checkPortValue(highP); err != nil {
8383
return errors.Wrap(err, fmt.Sprintf("last port of your range(%d)", lowP))
8484
}
8585

8686
if lowP > highP {
87-
return fmt.Errorf("First value of port range should be lower than the last port from your range: [%d, %d]", lowP, highP)
87+
return fmt.Errorf("first value of port range should be lower than the last port from your range: [%d, %d]", lowP, highP)
8888
}
8989

9090
for i := lowP; i <= highP; i++ {

common/httpx/httpx.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ func New(options *Options) (*HTTPX, error) {
155155

156156
if httpx.Options.Protocol == "http11" {
157157
// disable http2
158-
os.Setenv("GODEBUG", "http2client=0")
158+
_ = os.Setenv("GODEBUG", "http2client=0")
159159
transport.TLSNextProto = map[string]func(string, *tls.Conn) http.RoundTripper{}
160160
}
161161

@@ -359,7 +359,7 @@ func (h *HTTPX) getResponse(req *retryablehttp.Request, unsafeOptions UnsafeOpti
359359
func (h *HTTPX) doUnsafeWithOptions(req *retryablehttp.Request, unsafeOptions UnsafeOptions) (*http.Response, error) {
360360
method := req.Method
361361
headers := req.Header
362-
targetURL := req.URL.String()
362+
targetURL := req.String()
363363
body := req.Body
364364
options := rawhttp.DefaultOptions
365365
options.Timeout = h.Options.Timeout
@@ -424,6 +424,9 @@ func (h *HTTPX) SetCustomHeaders(r *retryablehttp.Request, headers map[string]st
424424
switch strings.ToLower(name) {
425425
case "host":
426426
r.Host = value
427+
if h.Options.Unsafe {
428+
r.Header.Set("Host", value)
429+
}
427430
case "cookie":
428431
// cookies are set in the default branch, and reset during the follow redirect flow
429432
fallthrough
@@ -435,6 +438,9 @@ func (h *HTTPX) SetCustomHeaders(r *retryablehttp.Request, headers map[string]st
435438
userAgent := useragent.PickRandom()
436439
r.Header.Set("User-Agent", userAgent.Raw) //nolint
437440
}
441+
if h.Options.AutoReferer && r.Header.Get("Referer") == "" {
442+
r.Header.Set("Referer", r.String())
443+
}
438444
}
439445

440446
func (httpx *HTTPX) setCustomCookies(req *http.Request) {
@@ -448,7 +454,7 @@ func (httpx *HTTPX) setCustomCookies(req *http.Request) {
448454
func (httpx *HTTPX) Sanitize(respStr string, trimLine, normalizeSpaces bool) string {
449455
respStr = httpx.htmlPolicy.Sanitize(respStr)
450456
if trimLine {
451-
respStr = strings.Replace(respStr, "\n", "", -1)
457+
respStr = strings.ReplaceAll(respStr, "\n", "")
452458
}
453459
if normalizeSpaces {
454460
respStr = httputilz.NormalizeSpaces(respStr)

0 commit comments

Comments
 (0)