package main import ( "crypto/md5" "errors" "flag" "fmt" "io" "io/ioutil" "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/internal/testdata" "github.com/lucas-clemente/quic-go/internal/utils" "github.com/lucas-clemente/quic-go/quictrace" ) type binds []string func (b binds) String() string { return strings.Join(b, ",") } func (b *binds) Set(v string) error { *b = strings.Split(v, ",") return nil } // Size is needed by the /demo/upload handler to determine the size of the uploaded file type Size interface { Size() int64 } // See https://en.wikipedia.org/wiki/Lehmer_random_number_generator func generatePRData(l int) []byte { res := make([]byte, l) seed := uint64(1) for i := 0; i < l; i++ { seed = seed * 48271 % 2147483647 res[i] = byte(seed) } return res } var tracer quictrace.Tracer func init() { 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 { log.Fatal(err) } } func setupHandler(www string, trace bool) http.Handler { mux := http.NewServeMux() if len(www) > 0 { mux.Handle("/", http.FileServer(http.Dir(www))) } else { mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Printf("%#v\n", r) const maxSize = 1 << 30 // 1 GB num, err := strconv.ParseInt(strings.ReplaceAll(r.RequestURI, "/", ""), 10, 64) if err != nil || num <= 0 || num > maxSize { w.WriteHeader(400) return } w.Write(generatePRData(int(num))) }) } 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, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x28, 0x01, 0x03, 0x00, 0x00, 0x00, 0xb6, 0x30, 0x2a, 0x2e, 0x00, 0x00, 0x00, 0x03, 0x50, 0x4c, 0x54, 0x45, 0x5a, 0xc3, 0x5a, 0xad, 0x38, 0xaa, 0xdb, 0x00, 0x00, 0x00, 0x0b, 0x49, 0x44, 0x41, 0x54, 0x78, 0x01, 0x63, 0x18, 0x61, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x01, 0xe2, 0xb8, 0x75, 0x22, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82, }) }) mux.HandleFunc("/demo/tiles", func(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "
") for i := 0; i < 200; i++ { fmt.Fprintf(w, `