package main import ( "bufio" "flag" "log" "net/http" "net/http/httputil" "net/url" "sync" "time" "github.com/ginuerzh/gost" "golang.org/x/net/http2" ) var ( requests, concurrency int quiet bool swg, ewg sync.WaitGroup ) func init() { log.SetFlags(log.LstdFlags | log.Lshortfile) flag.IntVar(&requests, "n", 1, "Number of requests to perform") flag.IntVar(&concurrency, "c", 1, "Number of multiple requests to make at a time") flag.BoolVar(&quiet, "q", false, "quiet mode") flag.BoolVar(&http2.VerboseLogs, "v", false, "HTTP2 verbose logs") flag.BoolVar(&gost.Debug, "d", false, "debug mode") flag.Parse() if quiet { gost.SetLogger(&gost.NopLogger{}) } } func main() { chain := gost.NewChain( /* // http+tcp gost.Node{ Addr: "127.0.0.1:18080", Client: gost.NewClient( gost.HTTPConnector(url.UserPassword("admin", "123456")), gost.TCPTransporter(), ), }, */ /* // socks5+tcp gost.Node{ Addr: "127.0.0.1:11080", Client: gost.NewClient( gost.SOCKS5Connector(url.UserPassword("admin", "123456")), gost.TCPTransporter(), ), }, */ /* // ss+tcp gost.Node{ Addr: "127.0.0.1:18338", Client: gost.NewClient( gost.ShadowConnector(url.UserPassword("chacha20", "123456")), gost.TCPTransporter(), ), }, */ /* // http+ws gost.Node{ Addr: "127.0.0.1:18000", Client: gost.NewClient( gost.HTTPConnector(url.UserPassword("admin", "123456")), gost.WSTransporter(nil), ), }, */ /* // http+wss gost.Node{ Addr: "127.0.0.1:18443", Client: gost.NewClient( gost.HTTPConnector(url.UserPassword("admin", "123456")), gost.WSSTransporter(nil), ), }, */ /* // http+tls gost.Node{ Addr: "127.0.0.1:11443", Client: gost.NewClient( gost.HTTPConnector(url.UserPassword("admin", "123456")), gost.TLSTransporter(), ), }, */ /* // http2 gost.Node{ Addr: "127.0.0.1:1443", Client: &gost.Client{ Connector: gost.HTTP2Connector(url.UserPassword("admin", "123456")), Transporter: gost.HTTP2Transporter(nil), }, }, */ /* // http+kcp gost.Node{ Addr: "127.0.0.1:18388", Client: gost.NewClient( gost.HTTPConnector(nil), gost.KCPTransporter(nil), ), }, */ /* // http+ssh gost.Node{ Addr: "127.0.0.1:12222", Client: gost.NewClient( gost.HTTPConnector(url.UserPassword("admin", "123456")), gost.SSHTunnelTransporter(), ), }, */ /* // http+quic gost.Node{ Addr: "localhost:6121", Client: &gost.Client{ Connector: gost.HTTPConnector(url.UserPassword("admin", "123456")), Transporter: gost.QUICTransporter(nil), }, }, */ // socks5+h2 gost.Node{ Addr: "localhost:8443", Client: &gost.Client{ // Connector: gost.HTTPConnector(url.UserPassword("admin", "123456")), Connector: gost.SOCKS5Connector(url.UserPassword("admin", "123456")), // Transporter: gost.H2CTransporter(), // HTTP2 h2c mode Transporter: gost.H2Transporter(nil), // HTTP2 h2 }, }, ) total := 0 for total < requests { if total+concurrency > requests { concurrency = requests - total } startChan := make(chan struct{}) for i := 0; i < concurrency; i++ { swg.Add(1) ewg.Add(1) go request(chain, startChan) } start := time.Now() swg.Wait() // wait for workers ready close(startChan) // start signal ewg.Wait() // wait for workers done duration := time.Since(start) total += concurrency log.Printf("%d/%d/%d requests done (%v/%v)", total, requests, concurrency, duration, duration/time.Duration(concurrency)) } } func request(chain *gost.Chain, start <-chan struct{}) { defer ewg.Done() swg.Done() <-start conn, err := chain.Dial("localhost:18888") if err != nil { log.Println(err) return } defer conn.Close() //conn = tls.Client(conn, &tls.Config{InsecureSkipVerify: true}) req, err := http.NewRequest(http.MethodGet, "http://localhost:18888", nil) if err != nil { log.Println(err) return } if err := req.Write(conn); err != nil { log.Println(err) return } resp, err := http.ReadResponse(bufio.NewReader(conn), req) if err != nil { log.Println(err) return } defer resp.Body.Close() if gost.Debug { rb, _ := httputil.DumpRequest(req, true) log.Println(string(rb)) rb, _ = httputil.DumpResponse(resp, true) log.Println(string(rb)) } }