mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-03 04:07:35 +03:00
add a tracing option to the example server
This commit is contained in:
parent
7c7b1ba9c7
commit
73f83ca4bb
2 changed files with 73 additions and 16 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
|||
debug
|
||||
debug.test
|
||||
main
|
||||
*.qtr
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue