Skip to content

Instantly share code, notes, and snippets.

@rnapier
Created October 23, 2014 13:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rnapier/dfbae391898e11c2598c to your computer and use it in GitHub Desktop.
Save rnapier/dfbae391898e11c2598c to your computer and use it in GitHub Desktop.
package main
import (
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"log"
"net"
"net/http"
"runtime"
"sync/atomic"
"time"
)
const port = ":8080"
const sampleInterval = 1 * time.Minute
var numConnections uint64
const cert = `
-----BEGIN CERTIFICATE-----
MIIDHDCCAm6gAwIBAgIJAJzp0JfeVFY6MA0GCSqGSIb3DQEBBQUAMFkxCzAJBgNV
BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
aWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMTCWxvY2FsaG9zdDAeFw0xNDEwMDMxODE3
MzZaFw0xNTEwMDMxODE3MzZaMFkxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21l
LVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNV
BAMTCWxvY2FsaG9zdDCBtTANBgkqhkiG9w0BAQEFAAOBowAwgZ8CgZcNdHU/8upi
8hRasgwlUXb6m/sOnVq3pKxZfnaehJCKDlEfkJqq91maQbDNflxd41J+3r6En2x/
eKJUvPJ/Lq5PsGTl127qYGElsgdcnJXpe7e2UZv/9OgJwq2sOtI+RwVpvs9ITPRU
caUPjmdKzyr4VwUEEj3fhBqnRSppz4pKtXK46ha+7UxWqU5pnPLLsssd+6/KIJzj
AgMBAAGjgb4wgbswHQYDVR0OBBYEFO7/91VllQERGVsizu9ijcmQ2q12MIGLBgNV
HSMEgYMwgYCAFO7/91VllQERGVsizu9ijcmQ2q12oV2kWzBZMQswCQYDVQQGEwJB
VTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0
cyBQdHkgTHRkMRIwEAYDVQQDEwlsb2NhbGhvc3SCCQCc6dCX3lRWOjAMBgNVHRME
BTADAQH/MA0GCSqGSIb3DQEBBQUAA4GYAAHFhLoveonNYbSYzJQ8XeyNNdaL/C9Y
U4GP19i6kmq5RN7y0qo9Z0ENpU1q3hZ79ruIQFitbiDXzECaE+YvclDfjUfiwdxe
6XYPvL/zqSwvKLXt47IrfJ+J8K5gi/bgGTJ+mdhfhSOupG3Kaz6LGZAcSh/B+I1J
tBA9k6n620VMNZQMQxooBXmkCYelSXuasRwBRSxMlAo=
-----END CERTIFICATE-----
`
const key = `
-----BEGIN RSA PRIVATE KEY-----
MIICwgIBAAKBlw10dT/y6mLyFFqyDCVRdvqb+w6dWrekrFl+dp6EkIoOUR+Qmqr3
WZpBsM1+XF3jUn7evoSfbH94olS88n8urk+wZOXXbupgYSWyB1yclel7t7ZRm//0
6AnCraw60j5HBWm+z0hM9FRxpQ+OZ0rPKvhXBQQSPd+EGqdFKmnPikq1crjqFr7t
TFapTmmc8suyyx37r8ognOMCAwEAAQKBlwH4qB0geBrbIQRQxdrJ3sbFB7mScHIr
nFzYXITJI2w2wMgBJcgayXQCX+cbtmjDH5kbBYrk2L6sbAxCSr07l6pxS7cpI0UP
rewZ810ZH6iLO8uPkKyBt/6cS8A5TPbA9E0CnD1+bHNrG08ZBejZsNoH6he2LrqO
yWbAJvgCGqha+o/KuWG3lYkEWsvS9/B7r2Pm0T5OwUECTAOyuw1GAH3Rdx5j+khI
LIiW/UEVlGeVqPkEjnwNqdOhpFcOli+S7fOs69w3sqwqo8w0LPXd5gfOFt/Tp3iW
UW9x6ZhhQDUaqAT7ztECTAOjZWZzWN9c5E5VP2/H+NVxCZ3a7LeJ5WntHJWyPTAv
YzBWQ73rz9Xk2vpablardo+26hb/dqYyhgS4TC01EOo7JUM384n1vf7WpXMCTAG3
dDZMGSxOD+IOfH4S6oEYvUP51WJjyQSWReF1ojA3ZwZ2IebBaCzlRrJ5NDnQrSm7
ymbycrWKx3lsUN+bvv9hPBJciiZcUkPF8xECTAJbutHC+RuoCfFgvsMFW513LSWe
kAyUnRmhcgLyy0jdnqzpbfXA0jKyquLXFWimsi6MAYcwxscKPub2U6KGIFXESu4c
aYfGvAZhOlMCTAGC8TM00Rz32cFJ6jGya5ILnfnF560gaKs93LiXNDwgLD2S22jq
25Kvpx/nt++36/RPxrAjnH4J0tJXu3hheqEXM06IhFXUMOBS3Qk=
-----END RSA PRIVATE KEY-----
`
func client() {
certPool := x509.NewCertPool()
if !certPool.AppendCertsFromPEM([]byte(cert)) {
log.Fatal("Could not load parse PEM")
}
tlsConfig := &tls.Config{
RootCAs: certPool,
ServerName: "localhost",
}
log.Printf("Client starting on %s\n", port)
for {
transport := &http.Transport{
TLSClientConfig: tlsConfig,
}
client := http.Client{Transport: transport}
res, err := client.Get(fmt.Sprintf("https://localhost%s/", port))
if err != nil {
log.Fatal(err)
}
_, err = ioutil.ReadAll(res.Body)
if err != nil {
log.Fatal(err)
}
res.Body.Close()
transport.CloseIdleConnections()
atomic.AddUint64(&numConnections, 1)
}
}
func httpHandler(w http.ResponseWriter, req *http.Request) {
w.Write([]byte(cert))
}
func server(gochan chan interface{}) {
mux := http.NewServeMux()
mux.HandleFunc("/", httpHandler)
srv := &http.Server{Addr: port, Handler: mux}
var err error
tlsConfig := &tls.Config{}
tlsConfig.NextProtos = []string{"http/1.1"}
tlsConfig.Certificates = make([]tls.Certificate, 1)
tlsConfig.Certificates[0], err = tls.X509KeyPair([]byte(cert), []byte(key))
if err != nil {
log.Fatal(err)
}
ln, err := net.Listen("tcp", port)
if err != nil {
log.Fatal(err)
}
tlsListener := tls.NewListener(ln, tlsConfig)
log.Printf("Server starting on %s\n", port)
close(gochan)
srv.Serve(tlsListener)
}
func main() {
gochan := make(chan interface{}, 1)
go server(gochan)
<-gochan
go client()
log.Printf("Sampling every %s\n", sampleInterval)
time.Sleep(sampleInterval)
var m runtime.MemStats
runtime.ReadMemStats(&m)
var startSys = m.Sys
var prevDSys uint64
for {
time.Sleep(sampleInterval)
runtime.ReadMemStats(&m)
dSys := m.Sys - startSys
var change string
if dSys != prevDSys {
change = "***"
} else {
change = ""
}
prevDSys = dSys
n := atomic.LoadUint64(&numConnections)
log.Printf("Alloc: %d\tSys: %d\tdSys: %d\tn: %d\t%s\n", m.Alloc, m.Sys, dSys, n, change)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment