Skip to content

Instantly share code, notes, and snippets.

@mikedanese
Last active October 17, 2019 22:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikedanese/a9204f541d1b12740be2551e381b99fc to your computer and use it in GitHub Desktop.
Save mikedanese/a9204f541d1b12740be2551e381b99fc to your computer and use it in GitHub Desktop.
package http
import (
"context"
"crypto/tls"
"errors"
"fmt"
"log"
"net"
"net/http"
"net/http/httptrace"
"sync"
"testing"
"time"
)
var bad struct {
sync.Mutex
val bool
}
type connWrapper struct {
net.Conn
}
func (cw *connWrapper) Write(b []byte) (n int, err error) {
bad.Lock()
defer bad.Unlock()
if bad.val {
log.Printf("bad=false")
bad.val = false
return 0, errors.New("broken pipe")
}
return cw.Conn.Write(b)
}
var trace = &httptrace.ClientTrace{
GotConn: func(info httptrace.GotConnInfo) {
log.Printf("conn: %#v", info)
},
TLSHandshakeDone: func(cfg tls.ConnectionState, err error) {
bad.Lock()
defer bad.Unlock()
log.Printf("bad=true")
bad.val = true
},
}
func dial(network, addr string) (net.Conn, error) {
c, err := net.Dial(network, addr)
if err != nil {
return nil, err
}
return &connWrapper{c}, nil
}
var cli = &http.Client{
Transport: &http.Transport{
ForceAttemptHTTP2: true,
Dial: dial,
DialContext: func(_ context.Context, network, addr string) (net.Conn, error) {
return dial(network, addr)
},
},
}
func TestBadCaching(t *testing.T) {
for {
do()
time.Sleep(1 * time.Second)
}
}
func do() {
req, err := http.NewRequest("GET", "https://container.googleapis.com", nil)
if err != nil {
log.Printf("err: %v\n", err)
return
}
req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
resp, err := cli.Do(req)
if err != nil {
log.Printf("err: %v\n", err)
return
}
fmt.Printf("status: %v\n", resp.Status)
defer resp.Body.Close()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment