add a tracing option to the example server

This commit is contained in:
Marten Seemann 2019-04-06 12:26:42 +09:00
parent 7c7b1ba9c7
commit 73f83ca4bb
2 changed files with 73 additions and 16 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
debug
debug.test
main
*.qtr

View file

@ -10,16 +10,19 @@ import (
"log"
"mime/multipart"
"net/http"
"os"
"strconv"
"strings"
"sync"
_ "net/http/pprof"
"github.com/lucas-clemente/quic-go"
"github.com/lucas-clemente/quic-go/http3"
"github.com/lucas-clemente/quic-go/integrationtests/tools/testserver"
"github.com/lucas-clemente/quic-go/internal/testdata"
"github.com/lucas-clemente/quic-go/internal/utils"
"github.com/lucas-clemente/quic-go/quictrace"
)
type binds []string
@ -38,8 +41,49 @@ type Size interface {
Size() int64
}
var tracer quictrace.Tracer
func init() {
http.HandleFunc("/demo/tile", func(w http.ResponseWriter, r *http.Request) {
tracer = quictrace.NewTracer()
}
func exportTraces() error {
traces := tracer.GetAllTraces()
if len(traces) != 1 {
return errors.New("expected exactly one trace")
}
for _, trace := range traces {
f, err := os.Create("trace.qtr")
if err != nil {
return err
}
if _, err := f.Write(trace); err != nil {
return err
}
f.Close()
fmt.Println("Wrote trace to", f.Name())
}
return nil
}
type tracingHandler struct {
handler http.Handler
}
var _ http.Handler = &tracingHandler{}
func (h *tracingHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h.handler.ServeHTTP(w, r)
if err := exportTraces(); err != nil {
panic(err)
}
}
func setupHandler(www string, trace bool) http.Handler {
mux := http.NewServeMux()
mux.Handle("/", http.FileServer(http.Dir(www)))
mux.HandleFunc("/demo/tile", func(w http.ResponseWriter, r *http.Request) {
// Small 40x40 png
w.Write([]byte{
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
@ -52,7 +96,7 @@ func init() {
})
})
http.HandleFunc("/demo/tiles", func(w http.ResponseWriter, r *http.Request) {
mux.HandleFunc("/demo/tiles", func(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "<html><head><style>img{width:40px;height:40px;}</style></head><body>")
for i := 0; i < 200; i++ {
fmt.Fprintf(w, `<img src="/demo/tile?cachebust=%d">`, i)
@ -60,7 +104,7 @@ func init() {
io.WriteString(w, "</body></html>")
})
http.HandleFunc("/demo/echo", func(w http.ResponseWriter, r *http.Request) {
mux.HandleFunc("/demo/echo", func(w http.ResponseWriter, r *http.Request) {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
fmt.Printf("error reading body while handling /echo: %s\n", err.Error())
@ -70,7 +114,7 @@ func init() {
// accept file uploads and return the MD5 of the uploaded file
// maximum accepted file size is 1 GB
http.HandleFunc("/demo/upload", func(w http.ResponseWriter, r *http.Request) {
mux.HandleFunc("/demo/upload", func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
err := r.ParseMultipartForm(1 << 30) // 1 GB
if err == nil {
@ -98,6 +142,21 @@ func init() {
<input type="submit">
</form></body></html>`)
})
http.HandleFunc("/dynamic/", func(w http.ResponseWriter, r *http.Request) {
const maxSize = 1 << 30 // 1 GB
num, err := strconv.ParseInt(strings.ReplaceAll(r.RequestURI, "/dynamic/", ""), 10, 64)
if err != nil || num <= 0 || num > maxSize {
w.WriteHeader(400)
return
}
w.Write(testserver.GeneratePRData(int(num)))
})
if !trace {
return mux
}
return &tracingHandler{handler: mux}
}
func main() {
@ -112,6 +171,7 @@ func main() {
flag.Var(&bs, "bind", "bind to")
www := flag.String("www", "/var/www", "www data")
tcp := flag.Bool("tcp", false, "also listen on TCP")
trace := flag.Bool("trace", false, "enable quic-trace")
flag.Parse()
logger := utils.DefaultLogger
@ -123,21 +183,16 @@ func main() {
}
logger.SetLogTimeFormat("")
http.Handle("/", http.FileServer(http.Dir(*www)))
http.HandleFunc("/dynamic/", func(w http.ResponseWriter, r *http.Request) {
const maxSize = 1 << 30 // 1 GB
num, err := strconv.ParseInt(strings.ReplaceAll(r.RequestURI, "/dynamic/", ""), 10, 64)
if err != nil || num <= 0 || num > maxSize {
w.WriteHeader(400)
return
}
w.Write(testserver.GeneratePRData(int(num)))
})
if len(bs) == 0 {
bs = binds{"localhost:6121"}
}
handler := setupHandler(*www, *trace)
var quicConf *quic.Config
if *trace {
quicConf = &quic.Config{QuicTracer: tracer}
}
var wg sync.WaitGroup
wg.Add(len(bs))
for _, b := range bs {
@ -149,7 +204,8 @@ func main() {
err = http3.ListenAndServe(bCap, certFile, keyFile, nil)
} else {
server := http3.Server{
Server: &http.Server{Addr: bCap},
Server: &http.Server{Handler: handler, Addr: bCap},
QuicConfig: quicConf,
}
err = server.ListenAndServeTLS(testdata.GetCertificatePaths())
}