bodyclose is a static analysis tool which checks whether res.Body is correctly closed.

bodyclose

CircleCI

bodyclose is a static analysis tool which checks whether res.Body is correctly closed.

Install

You can get bodyclose by go get command.

$ go get -u github.com/timakin/bodyclose

How to use

bodyclose run with go vet as below when Go is 1.12 and higher.

$ go vet -vettool=$(which bodyclose) github.com/timakin/go_api/...
# github.com/timakin/go_api
internal/httpclient/httpclient.go:13:13: response body must be closed

When Go is lower than 1.12, just run bodyclose command with the package name (import path).

But it cannot accept some options such as --tags.

$ bodyclose github.com/timakin/go_api/...
~/go/src/github.com/timakin/api/internal/httpclient/httpclient.go:13:13: response body must be closed

Analyzer

bodyclose validates whether *net/http.Response of HTTP request calls method Body.Close() such as below code.

resp, err := http.Get("http://example.com/") // Wrong case
if err != nil {
	// handle error
}
body, err := ioutil.ReadAll(resp.Body)

This code is wrong. You must call resp.Body.Close when finished reading resp.Body.

resp, err := http.Get("http://example.com/")
if err != nil {
	// handle error
}
defer resp.Body.Close() // OK
body, err := ioutil.ReadAll(resp.Body)

In the GoDoc of Client.Do this rule is clearly described.

If you forget this sentence, a HTTP client cannot re-use a persistent TCP connection to the server for a subsequent "keep-alive" request.

Owner
Comments
  • The following program is not handled correctly

    The following program is not handled correctly

    package main
    
    import (
    	"io"
    	"net/http"
    )
    
    func closeBody(c io.Closer) {
    	_ = c.Close()
    }
    
    func main() {
    	resp, _ := http.Get("https://example.com")
    	defer closeBody(resp.Body)
    }
    
  • SSA and generics (go1.18)

    SSA and generics (go1.18)

    Currently, SSA is not working with generics.

    So your linter produces a panic when it is used with generics.

    There is an issue open about that in the Go repository: https://github.com/golang/go/issues/48525

    Inside golangci-lint, we have disabled your linters: https://github.com/golangci/golangci-lint/issues/2649

    You have 2 solutions:

    • waiting for a version of SSA that will support generics
    • dropping the SSA analyzers and using something else to analyze the code.

    Related to https://github.com/golang/go/issues/50558

  • fix: panic.

    fix: panic.

    https://github.com/golangci/golangci-lint/issues/733

    WARN [linters context] Panic: bodyclose: package "phttp" (isInitialPkg: true, needAnalyzeSource: true): runtime error: invalid memory address or nil pointer dereference: goroutine 47307 [running]:
    runtime/debug.Stack(0xf57075, 0x3c, 0xc00167d8b8)
            /usr/local/go/src/runtime/debug/stack.go:24 +0x9d
    github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*action).analyzeSafe.func1(0xc034cff740)
            /Users/denis/go/src/github.com/golangci/golangci-lint/pkg/golinters/goanalysis/runner.go:404 +0x1af
    panic(0xd9a0e0, 0x1720290)
            /usr/local/go/src/runtime/panic.go:679 +0x1b2
    go/types.(*object).Name(...)
            /usr/local/go/src/go/types/object.go:133
    github.com/timakin/bodyclose/passes/bodyclose.(*runner).calledInFunc(0xc00167dc78, 0xc0b624d7c0, 0xc0b6512800, 0x10ae3a0)
            /Users/denis/go/src/github.com/golangci/golangci-lint/vendor/github.com/timakin/bodyclose/passes/bodyclose/bodyclose.go:328 +0x284
    github.com/timakin/bodyclose/passes/bodyclose.(*runner).isopen(0xc00167dc78, 0xc0b6476580, 0x14, 0x0)
            /Users/denis/go/src/github.com/golangci/golangci-lint/vendor/github.com/timakin/bodyclose/passes/bodyclose/bodyclose.go:148 +0x555
    github.com/timakin/bodyclose/passes/bodyclose.runner.run(0xc0a41bfc20, 0x10b9cc0, 0xc020a70910, 0xc0b6fc58e0, 0x10b9d60, 0xc020aea690, 0xc003d10c80, 0xc0b6f71a10, 0xc0a41bfc20, 0xe41140933e432942, ...)
            /Users/denis/go/src/github.com/golangci/golangci-lint/vendor/github.com/timakin/bodyclose/passes/bodyclose/bodyclose.go:102 +0x589
    github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*action).analyze(0xc034cff740)
            /Users/denis/go/src/github.com/golangci/golangci-lint/pkg/golinters/goanalysis/runner.go:495 +0x87a
    github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*action).analyzeSafe(0xc034cff740)
            /Users/denis/go/src/github.com/golangci/golangci-lint/pkg/golinters/goanalysis/runner.go:407 +0x5b
    github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*loadingPackage).analyze.func3(0xc09f24a800, 0xc034cff740)
            /Users/denis/go/src/github.com/golangci/golangci-lint/pkg/golinters/goanalysis/runner.go:961 +0x69
    created by github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*loadingPackage).analyze
            /Users/denis/go/src/github.com/golangci/golangci-lint/pkg/g
    
  • False Positives on Methods/Functions That Return *http.Response

    False Positives on Methods/Functions That Return *http.Response

    For functions and methods that return a *http.Response and handle the closing of the response body by the function/method caller, this tool flags the response inside the function/method as needing to be closed, when it is being closed by the caller.

  • Nil pointer deref in runner.run

    Nil pointer deref in runner.run

    panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x1 addr=0x50 pc=0x9a694f]
    
    goroutine 18969 [running]:
    github.com/timakin/bodyclose/passes/bodyclose.(*runner).run(0xc0000c6d40, 0xc150d96f00, 0x10, 0xd4f8e0, 0xdf189b62edaedd01, 0xc2d16e0ac0)
    	/go/src/github.com/foo/bar/vendor/github.com/timakin/bodyclose/passes/bodyclose/bodyclose.go:57 +0x1af
    github.com/golangci/golangci-lint/pkg/golinters/goanalysis/checker.(*action).execOnce(0xc06bf7d540)
    	/go/src/github.com/foo/bar/vendor/github.com/golangci/golangci-lint/pkg/golinters/goanalysis/checker/checker.go:382 +0x68a
    sync.(*Once).Do(0xc06bf7d540, 0xc00189e790)
    	/usr/local/go/src/sync/once.go:44 +0xb3
    github.com/golangci/golangci-lint/pkg/golinters/goanalysis/checker.(*action).exec(0xc06bf7d540)
    	/go/src/github.com/foo/bar/vendor/github.com/golangci/golangci-lint/pkg/golinters/goanalysis/checker/checker.go:303 +0x50
    github.com/golangci/golangci-lint/pkg/golinters/goanalysis/checker.execAll.func1(0xc06bf7d540)
    	/go/src/github.com/foo/bar/vendor/github.com/golangci/golangci-lint/pkg/golinters/goanalysis/checker/checker.go:291 +0x34
    created by github.com/golangci/golangci-lint/pkg/golinters/goanalysis/checker.execAll
    	/go/src/github.com/foo/bar/vendor/github.com/golangci/golangci-lint/pkg/golinters/goanalysis/checker/checker.go:297 +0x11b
    

    I encountered this when running bodyclose through golangci-lint. The stack trace seems to point the finger at this line. AFAICT r.resObj.Type() must be returning nil.

    Unfortunately, the code that triggered this is private so I can't share it with you 🙁

    golangci-lint v1.17.1
    go version 1.12.6
    
  • fix: call method nil.

    fix: call method nil.

    The following sample panic:

    func issue() {
    	resp, _ := http.Get("https://example.com")
    	reader := http.MaxBytesReader(nil, resp.Body, 1024*1024)
    	fmt.Println(reader)
    }
    
    panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x649024]
    
    goroutine 1183 [running]:
    go/types.(*object).Name(...)
    	/home/ldez/.gvm/gos/go1.12.5/src/go/types/object.go:134
    github.com/timakin/bodyclose/passes/bodyclose.(*runner).isCloseCall(0xc0000d0700, 0x804400, 0xc00874e280, 0xc001a28360)
    	/home/ldez/sources/go/src/github.com/timakin/bodyclose/passes/bodyclose/bodyclose.go:230 +0x234
    github.com/timakin/bodyclose/passes/bodyclose.(*runner).isopen(0xc0000d0700, 0xc0091909a0, 0x0, 0xc005e44400)
    	/home/ldez/sources/go/src/github.com/timakin/bodyclose/passes/bodyclose/bodyclose.go:175 +0x2e9
    github.com/timakin/bodyclose/passes/bodyclose.(*runner).run(0xc0000d0700, 0xc004912750, 0x10, 0x734b80, 0x4519bc3afd235501, 0xc008049190)
    	/home/ldez/sources/go/src/github.com/timakin/bodyclose/passes/bodyclose/bodyclose.go:100 +0x641
    golang.org/x/tools/go/analysis/internal/checker.(*action).execOnce(0xc005e1e3c0)
    	/home/ldez/sources/go/pkg/mod/golang.org/x/[email protected]/go/analysis/internal/checker/checker.go:513 +0x68a
    sync.(*Once).Do(0xc005e1e3c0, 0xc000047790)
    	/home/ldez/.gvm/gos/go1.12.5/src/sync/once.go:44 +0xb3
    golang.org/x/tools/go/analysis/internal/checker.(*action).exec(0xc005e1e3c0)
    	/home/ldez/sources/go/pkg/mod/golang.org/x/[email protected]/go/analysis/internal/checker/checker.go:434 +0x50
    golang.org/x/tools/go/analysis/internal/checker.execAll.func1(0xc005e1e3c0)
    	/home/ldez/sources/go/pkg/mod/golang.org/x/[email protected]/go/analysis/internal/checker/checker.go:422 +0x34
    created by golang.org/x/tools/go/analysis/internal/checker.execAll
    	/home/ldez/sources/go/pkg/mod/golang.org/x/[email protected]/go/analysis/internal/checker/checker.go:428 +0x11b
    

    another sample:

    func issue5() {
    	resp, _ := http.Get("https://example.com")
    	foo(resp.Body)
    }
    
    func foo(r io.ReadCloser) {}
    

    I'm not sure about the fix.

  • panic: runtime error: invalid memory address or nil pointer dereference

    panic: runtime error: invalid memory address or nil pointer dereference

    panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x11f5d44]
    
    goroutine 49 [running]:
    go/types.(*object).Name(...)
    	/usr/local/Cellar/go/1.12.1/libexec/src/go/types/object.go:134
    github.com/timakin/bodyclose/passes/bodyclose.(*runner).isCloseCall(0xc00004a380, 0x13fd500, 0xc0002eda40, 0xc0003045a0)
    	/Users/dcuadrado/Projects/GoCode/src/github.com/timakin/bodyclose/passes/bodyclose/bodyclose.go:226 +0x294
    github.com/timakin/bodyclose/passes/bodyclose.(*runner).isopen(0xc00004a380, 0xc000302790, 0x0, 0xc00033c4e0)
    	/Users/dcuadrado/Projects/GoCode/src/github.com/timakin/bodyclose/passes/bodyclose/bodyclose.go:175 +0x2e9
    github.com/timakin/bodyclose/passes/bodyclose.(*runner).run(0xc00004a380, 0xc0000a85a0, 0x10a5c26, 0x5ca8c59a, 0x50dd49c16cc1328, 0x74254feed292)
    	/Users/dcuadrado/Projects/GoCode/src/github.com/timakin/bodyclose/passes/bodyclose/bodyclose.go:100 +0x641
    golang.org/x/tools/go/analysis/unitchecker.run.func5.1()
    	/Users/dcuadrado/Projects/GoCode/src/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go:342 +0x6c1
    sync.(*Once).Do(0xc0002b93b0, 0xc000035728)
    	/usr/local/Cellar/go/1.12.1/libexec/src/sync/once.go:44 +0xb3
    golang.org/x/tools/go/analysis/unitchecker.run.func5(0x1630500, 0x0)
    	/Users/dcuadrado/Projects/GoCode/src/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go:302 +0x195
    golang.org/x/tools/go/analysis/unitchecker.run.func6.1(0xc00000fe70, 0xc00040ed70, 0x1630500)
    	/Users/dcuadrado/Projects/GoCode/src/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go:354 +0x33
    created by golang.org/x/tools/go/analysis/unitchecker.run.func6
    	/Users/dcuadrado/Projects/GoCode/src/golang.org/x/tools/go/analysis/unitchecker/unitchecker.go:353 +0xa3
    
  • Handle more cases — round 1

    Handle more cases — round 1

    We experienced a crash of one of our production services a couple of weeks ago due to an un-closed HTTP response body. This change covers more cases which would have detected the problem and prevented the crash.

    image

  • Do not filter out files without net/http

    Do not filter out files without net/http

    Seems like we should not filter out files without net/http import. Here's the case:

    helper.go:

    package a
    
    import "net/http"
    
    func doRequest(string url) (*http.Response, error) {
        return http.Get(url)
    }
    

    main.go:

    package a
    
    func doStuff() {
        resp, err := doRequest("https://example.com/")
        // ...
    }
    

    resp.Body remains opened but since main.go doesn't have net/http import analyzer skips it.

    Same happens when you use something like ctxhttp.

  • False positive: if function returns io.ReadCloser

    False positive: if function returns io.ReadCloser

    Example:

    func download(url string) (io.ReadCloser, error) { // body should be closed by User
    	r, err := http.DefaultClient.Get(url)
    	if err != nil {
    		return nil, err
    	}
    	return r.Body, nil
    }
    
  • False Positive when http.Response from a function

    False Positive when http.Response from a function

    The following code triggers a false positive.

    
    package main
    
    import (
    	"net/http"
    	"tmp"
    )
    
    type MyResp struct {
    	resp *http.Response
    }
    
    func (r *MyResp) Response() *http.Response {
    	return r.resp
    }
    
    func test() {
    	tmp := &MyResp{}
    	var err error
    	tmp.resp, err = http.Get("http://example.com/")
    	if err != nil {
    		fmt.Println(err)
    	}
    	defer tmp.Response().Body.Close()
    	body, _ := ioutil.ReadAll(tmp.Response().Body)
    	fmt.Println(body)
    }
    
    func main() {
            test()
    }
    
    
    
  • false positive when close is in another package

    false positive when close is in another package

    The following code triggers a false positive.

    package util
    
    import (
    	"io"
    	"log"
    )
    
    func Close(c io.Closer) {
    	if err := c.Close(); err != nil {
    		log.Printf("error closing io: %w", err)
    	}
    }
    
    package main
    
    import (
    	"net/http"
    	"util"
    )
    
    func main() {
    	res, _ := http.Get("http://example.com/")
    	defer util.Close(res.Body)
    }
    
  • global resp cause check panic

    global resp cause check panic

    
    var resp *http.Response
    
    func testGlobal() {
    	resp, _ = http.Get("https://example.com")
    	resp.Body.Close()
    
    }
    
    

    It cause panic when check this code.

    
    ERRO [runner] Panic: bodyclose: package "main" (isInitialPkg: true, needAnalyzeSource: true): runtime error: invalid memory address or nil pointer dereference: goroutine 4224 [running]:
    runtime/debug.Stack()
    	runtime/debug/stack.go:24 +0x65
    github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*action).analyzeSafe.func1()
    	github.com/golangci/golangci-lint/pkg/golinters/goanalysis/runner_action.go:101 +0x155
    panic({0x4aeda60, 0x557d2c0})
    	runtime/panic.go:1038 +0x215
    github.com/timakin/bodyclose/passes/bodyclose.(*runner).isopen(0xc003c2dd08, 0xc01d94f770, 0x4)
    	github.com/timakin/[email protected]/passes/bodyclose/bodyclose.go:135 +0x18d
    github.com/timakin/bodyclose/passes/bodyclose.runner.run({0xc014270f70, {0x4e5caf8, 0xc0024143c0}, 0xc01d94f770, {0x4e5cb98, 0xc0024145f0}, 0xc000da2640, 0xc01b888a20}, 0xc014270f70)
    	github.com/timakin/[email protected]/passes/bodyclose/bodyclose.go:102 +0x5c5
    github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*action).analyze(0xc0003b4300)
    	github.com/golangci/golangci-lint/pkg/golinters/goanalysis/runner_action.go:187 +0x9c4
    github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*action).analyzeSafe.func2()
    	github.com/golangci/golangci-lint/pkg/golinters/goanalysis/runner_action.go:105 +0x1d
    github.com/golangci/golangci-lint/pkg/timeutils.(*Stopwatch).TrackStage(0xc001a0e8c0, {0x4c2232d, 0x9}, 0xc002c0d760)
    	github.com/golangci/golangci-lint/pkg/timeutils/stopwatch.go:111 +0x4a
    github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*action).analyzeSafe(0xc0003b4300)
    	github.com/golangci/golangci-lint/pkg/golinters/goanalysis/runner_action.go:104 +0x85
    github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*loadingPackage).analyze.func2(0x0)
    	github.com/golangci/golangci-lint/pkg/golinters/goanalysis/runner_loadingpackage.go:80 +0x67
    created by github.com/golangci/golangci-lint/pkg/golinters/goanalysis.(*loadingPackage).analyze
    	github.com/golangci/golangci-lint/pkg/golinters/goanalysis/runner_loadingpackage.go:75 +0x1fd
    
    
  • False positive with body close inside separate function

    False positive with body close inside separate function

    I think that bodyclose produces false positive warning on this code: response body is closed in a separate function inside each logic case. I can not use defer response.Body.Close() due to infinite loop with ticker.

    func isAppReady(
    	logger *zap.Logger,
    	shutdownChannel <-chan bool,
    	appHost string,
    	appHealthCheckURI string,
    	appCheckFrequency int,
    ) bool {
    	logger.Debug(
    		"[Consumer] check that App is available in the infinite loop with frequency",
    		zap.Int("appCheckFrequency", appCheckFrequency),
    		zap.String("app url", appHost+appHealthCheckURI),
    	)
    
    	ticker := time.NewTicker(time.Duration(appCheckFrequency) * time.Second)
    	for {
    		select {
    		case <-shutdownChannel:
    			logger.Info("[Consumer] got Shutdown signal, terminating app health check")
    			return false
    		case <-ticker.C:
    			response, err := http.Get(appHost + appHealthCheckURI)
    			if err != nil {
    				logger.Error("[Consumer] error after the app health check request", zap.Error(err))
    				closeResponse(response.Body, logger)
    				continue
    			}
    			if response.StatusCode == http.StatusOK {
    				logger.Info("[Consumer] got 200 OK: application started",
    					zap.String("app url", appHost+appHealthCheckURI),
    					zap.Int("response.StatusCode", response.StatusCode),
    				)
    				closeResponse(response.Body, logger)
    				return true
    			}
    
    			closeResponse(response.Body, logger)
    			logger.Debug(
    				"[Consumer] app is not ready yet to consume events, continue to wait",
    				zap.String("app url", appHost+appHealthCheckURI),
    				zap.Int("response.StatusCode", response.StatusCode),
    			)
    		}
    	}
    }
    
    func closeResponse(responseBody io.Closer, logger *zap.Logger) {
    	if err := responseBody.Close(); err != nil {
    		logger.Error("[Consumer] can not close the response")
    	}
    }
    
  • False positive with a retry for

    False positive with a retry for

    The following code is fine, because it closes the body only when the error is nil, but gets response body must be closed errors on both the d.client.Do(req) lines.

    func (d *Dispatcher) call(req *http.Request) {
    	// keep retrying the request until the error is nil
    	tries := 0
    	wait := time.Second
    	resp, err := d.client.Do(req)
    	for err != nil && tries < d.retries {
    		// wait a while
    		time.Sleep(wait)
    		wait *= 2
    		// try again
    		resp, err = d.client.Do(req)
    		tries++
    	}
    
    	// maximum retries exceeded
    	if err != nil {
    		// log error here
    		return
    	}
    
    	// now the request was successful; do some work
    
    	// close the body now
    	if err = resp.Body.Close(); err != nil {
    		// log error
    	}
    }
    
netscanner - TCP/UDP scanner to find open or closed ports

netscanner netscanner - TCP/UDP scanner to find open or closed ports installation you have to run this command to install the program $ go get github.

Dec 19, 2022
Fast Static File Analysis Framework
Fast Static File Analysis Framework

Florentino; Fast Static File Analysis Framework Story Florentino is named after a fiction warrior. Flarentino: "I'd wear a fedora but they haven't inv

Nov 9, 2022
Get subdomain list and check whether they are active or not by each response code. Using API by c99.nl
Get subdomain list and check whether they are active or not by each response code. Using API by c99.nl

getsubdomain Get subdomain list and check whether they are active or not by each response code. Using API by c99.nl Installation â–ļ go install github.c

Oct 24, 2022
checkip is a CLI tool and library that checks an IP address using various public services.
checkip is a CLI tool and library that checks an IP address using various public services.

checkip is a CLI tool and library that checks an IP address using various public services.

Dec 20, 2022
Checks sneaker availability, currently Asos/JD/Nike + Air Force 1 '07 44 only

airforce Setup Requires a .env file with Twilio credentials and phone numbers. SID=AC0ae6d46612d3a0c3d49977485652f665 TOKEN=7ff8d07a7d0fc9e6432a14ad84

Dec 12, 2021
HCio is a straightforward way to ping Healthchecks.io checks directly from a Go application

HCio HCio is a straightforward way to ping Healthchecks.io checks directly from a Go application. Getting Started Create a simple Check: check := hcio

Nov 20, 2022
Cross check makes health checks on PostgreSQL and MySQL database servers

Cross Check Cross check makes health checks on PostgreSQL and MySQL database servers, it also performs master & slave control for clusters in H/A Acti

Jan 14, 2022
A Go module that checks a domain's email information

mail-checker This checks a domain's email information, if it has DMARC, SPF Record, and or a Mail Server Bitcoin donations are welcome: 1J2aMYUnkPXkzE

Nov 10, 2022
All-in-one Network Gateway for Malware analysis

aio-gw [EXPERIMENTAL]: All-in-one Network Gateway for Malware analysis. currently at Alpha stage. HELP NEEDED: if you're keen to contribute to aio-gw,

Dec 14, 2022
This is a Go port of the phase vocoding analysis/resynthesis routines from Tom Erbe's program "SoundHack".

Overview This is a Go port of the phase vocoding analysis/resynthesis routines from Tom Erbe's program "SoundHack". Unlike the original SoundHack, thi

Apr 24, 2022
Simple, secure and modern Go HTTP server to serve static sites, single-page applications or a file with ease

srv srv is a simple, secure and modern HTTP server, written in Go, to serve static sites, single-page applications or a file with ease. You can use it

Sep 7, 2022
Reverse Proxying + Static File Serving + Let's Encrypt + multiple hosts

Slashing This is a HTTPS server, which aims to replace my personal nginx usages. Currently, it serves Reverse Proxying (e.g. to a Python-Flask,Java,PH

Jul 29, 2021
`kawipiko` -- blazingly fast static HTTP server -- focused on low latency and high concurrency, by leveraging Go, `fasthttp` and the CDB embedded database
`kawipiko` -- blazingly fast static HTTP server -- focused on low latency and high concurrency, by leveraging Go, `fasthttp` and the CDB embedded database

kawipiko -- blazingly fast static HTTP server kawipiko is a lightweight static HTTP server written in Go; focused on serving static content as fast an

Jan 3, 2023
JSON assets that are almost static like house_id mappings for the API.

TibiaData API assets JSON assets that are almost static like house_id mappings for the API. This repo contains tooling that generates the assets json

Dec 15, 2022
Static file server that service content required by dan's services

Static file server that service content required by dan's services.

Jan 20, 2022
Http-recorder - Application for record http response as static files
Http-recorder - Application for record http response as static files

http-recorder This is a application for record http response as static files. Th

Mar 21, 2022
serve a static website as a .onion hidden service

hidden service server A CLI that will host a static website as a .onion hidden service. Comes with an additional binary that can be used to generate v

Sep 4, 2022
red-tldr is a lightweight text search tool, which is used to help red team staff quickly find the commands and key points they want to execute, so it is more suitable for use by red team personnel with certain experience.
red-tldr is a lightweight text search tool, which is used to help red team staff quickly find the commands and key points they want to execute, so it is more suitable for use by red team personnel with certain experience.

Red Team TL;DR English | 中文įŽ€äŊ“ What is Red Team TL;DR ? red-tldr is a lightweight text search tool, which is used to help red team staff quickly find t

Jan 5, 2023
A small tool used to correspond to the IP address according to the name, id, and network alias of the docker container, which can be run as a DNS server

A small tool used to correspond to the IP address according to the name, id, and network alias of the docker container, which can be run as a DNS server

Apr 4, 2022