mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-02 19:57:35 +03:00
uTLS is not yet bumped to the new version, so this commit breaks the dependencies relationship by getting rid of the local replace.
111 lines
2.5 KiB
Go
111 lines
2.5 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"context"
|
|
"crypto/x509"
|
|
"flag"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"sync"
|
|
|
|
tls "github.com/refraction-networking/utls"
|
|
|
|
quic "github.com/refraction-networking/uquic"
|
|
"github.com/refraction-networking/uquic/http3"
|
|
"github.com/refraction-networking/uquic/internal/testdata"
|
|
"github.com/refraction-networking/uquic/internal/utils"
|
|
"github.com/refraction-networking/uquic/logging"
|
|
"github.com/refraction-networking/uquic/qlog"
|
|
)
|
|
|
|
func main() {
|
|
verbose := flag.Bool("v", false, "verbose")
|
|
quiet := flag.Bool("q", false, "don't print the data")
|
|
keyLogFile := flag.String("keylog", "", "key log file")
|
|
insecure := flag.Bool("insecure", false, "skip certificate verification")
|
|
enableQlog := flag.Bool("qlog", false, "output a qlog (in the same directory)")
|
|
flag.Parse()
|
|
urls := flag.Args()
|
|
|
|
logger := utils.DefaultLogger
|
|
|
|
if *verbose {
|
|
logger.SetLogLevel(utils.LogLevelDebug)
|
|
} else {
|
|
logger.SetLogLevel(utils.LogLevelInfo)
|
|
}
|
|
logger.SetLogTimeFormat("")
|
|
|
|
var keyLog io.Writer
|
|
if len(*keyLogFile) > 0 {
|
|
f, err := os.Create(*keyLogFile)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer f.Close()
|
|
keyLog = f
|
|
}
|
|
|
|
pool, err := x509.SystemCertPool()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
testdata.AddRootCA(pool)
|
|
|
|
var qconf quic.Config
|
|
if *enableQlog {
|
|
qconf.Tracer = func(ctx context.Context, p logging.Perspective, connID quic.ConnectionID) logging.ConnectionTracer {
|
|
filename := fmt.Sprintf("client_%x.qlog", connID)
|
|
f, err := os.Create(filename)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
log.Printf("Creating qlog file %s.\n", filename)
|
|
return qlog.NewConnectionTracer(utils.NewBufferedWriteCloser(bufio.NewWriter(f), f), p, connID)
|
|
}
|
|
}
|
|
roundTripper := &http3.RoundTripper{
|
|
TLSClientConfig: &tls.Config{
|
|
RootCAs: pool,
|
|
InsecureSkipVerify: *insecure,
|
|
KeyLogWriter: keyLog,
|
|
},
|
|
QuicConfig: &qconf,
|
|
}
|
|
defer roundTripper.Close()
|
|
hclient := &http.Client{
|
|
Transport: roundTripper,
|
|
}
|
|
|
|
var wg sync.WaitGroup
|
|
wg.Add(len(urls))
|
|
for _, addr := range urls {
|
|
logger.Infof("GET %s", addr)
|
|
go func(addr string) {
|
|
rsp, err := hclient.Get(addr)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
logger.Infof("Got response for %s: %#v", addr, rsp)
|
|
|
|
body := &bytes.Buffer{}
|
|
_, err = io.Copy(body, rsp.Body)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
if *quiet {
|
|
logger.Infof("Response Body: %d bytes", body.Len())
|
|
} else {
|
|
logger.Infof("Response Body:")
|
|
logger.Infof("%s", body.Bytes())
|
|
}
|
|
wg.Done()
|
|
}(addr)
|
|
}
|
|
wg.Wait()
|
|
}
|