Created
January 24, 2021 13:34
-
-
Save erikdubbelboer/f14b38d258f376dd6d4d47491f32535a to your computer and use it in GitHub Desktop.
Revisions
-
erikdubbelboer created this gist
Jan 24, 2021 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,219 @@ package main import ( "crypto/rand" "crypto/rsa" "crypto/tls" "crypto/x509" "crypto/x509/pkix" "encoding/pem" "fmt" "io/ioutil" "math/big" "net" "net/http" "runtime" "sync/atomic" "time" "github.com/valyala/fasthttp" ) func main() { caCert, key, err := GenerateCert("localhost") if err != nil { panic(err) } caCertPool := x509.NewCertPool() if !caCertPool.AppendCertsFromPEM(caCert) { panic("not ok") } caCertPool.AppendCertsFromPEM(caCert) cert, err := tls.X509KeyPair(caCert, key) if err != nil { panic(err) } go server(caCertPool, cert) time.Sleep(time.Second) // fasthttpClient(caCertPool, cert) httpClient(caCertPool, cert) } func server(caCertPool *x509.CertPool, cert tls.Certificate) { // Create the TLS Config with the CA pool and enable Client certificate validation cfg := &tls.Config{ ClientCAs: caCertPool, ClientAuth: tls.RequireAndVerifyClientCert, Certificates: []tls.Certificate{cert}, } cfg.BuildNameToCertificate() ln, err := net.Listen("tcp4", "localhost:8443") if err != nil { panic(err) } lnTls := tls.NewListener(ln, cfg) server := &fasthttp.Server{ IdleTimeout: 30 * time.Second, TCPKeepalive: true, TCPKeepalivePeriod: 30 * time.Second, MaxConnsPerIP: 200, Handler: func(ctx *fasthttp.RequestCtx) { ctx.SetStatusCode(200) ctx.SetBody([]byte("hello")) }, } if err := server.Serve(lnTls); err != nil { panic(err) } } func fasthttpClient(caCertPool *x509.CertPool, cert tls.Certificate) { client := &fasthttp.Client{ TLSConfig: &tls.Config{ RootCAs: caCertPool, Certificates: []tls.Certificate{cert}, ClientSessionCache: tls.NewLRUClientSessionCache(64), }, } var requests int64 worker := func() { for { req := fasthttp.AcquireRequest() res := fasthttp.AcquireResponse() req.SetRequestURI("https://localhost:8443/") if err := client.Do(req, res); err != nil { println(err.Error()) } atomic.AddInt64(&requests, 1) fasthttp.ReleaseRequest(req) fasthttp.ReleaseResponse(res) } } for i := 0; i < 4; i++ { go worker() } // Print the request counters every second. for { time.Sleep(time.Second) r := atomic.SwapInt64(&requests, 0) fmt.Println(r, runtime.NumGoroutine()) } } func httpClient(caCertPool *x509.CertPool, cert tls.Certificate) { client := &http.Client{ Transport: &http.Transport{ TLSHandshakeTimeout: 5 * time.Second, MaxIdleConns: 2000, MaxIdleConnsPerHost: 200, MaxConnsPerHost: 2000, IdleConnTimeout: 20 * time.Second, WriteBufferSize: 1024, ReadBufferSize: 1024, TLSClientConfig: &tls.Config{ RootCAs: caCertPool, Certificates: []tls.Certificate{cert}, ClientSessionCache: tls.NewLRUClientSessionCache(64), }, }, } var requests int64 worker := func() { for { if res, err := client.Get("https://localhost:8443/"); err != nil { println(err.Error()) } else { _, err := ioutil.ReadAll(res.Body) if err != nil { panic(err) } } atomic.AddInt64(&requests, 1) } } for i := 0; i < 4; i++ { go worker() } // Print the request counters every second. for { time.Sleep(time.Second) r := atomic.SwapInt64(&requests, 0) fmt.Println(r, runtime.NumGoroutine()) } } // GenerateCert generates certificate and private key based on the given host. func GenerateCert(host string) ([]byte, []byte, error) { priv, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return nil, nil, err } serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) if err != nil { return nil, nil, err } cert := &x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ Organization: []string{"I have your data"}, }, NotBefore: time.Now(), NotAfter: time.Now().Add(365 * 24 * time.Hour), KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth}, SignatureAlgorithm: x509.SHA256WithRSA, DNSNames: []string{host}, BasicConstraintsValid: true, IsCA: true, } certBytes, err := x509.CreateCertificate( rand.Reader, cert, cert, &priv.PublicKey, priv, ) p := pem.EncodeToMemory( &pem.Block{ Type: "PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv), }, ) b := pem.EncodeToMemory( &pem.Block{ Type: "CERTIFICATE", Bytes: certBytes, }, ) return b, p, err }