137 lines
3.5 KiB
Go
137 lines
3.5 KiB
Go
package wt_test
|
|
|
|
import (
|
|
"context"
|
|
"crypto/ecdsa"
|
|
"crypto/elliptic"
|
|
"crypto/rand"
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"crypto/x509/pkix"
|
|
"fmt"
|
|
"io"
|
|
"math/big"
|
|
"net"
|
|
"net/http"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/centrifugal/centrifugo/v6/internal/middleware"
|
|
"github.com/quic-go/quic-go"
|
|
"github.com/quic-go/quic-go/http3"
|
|
"github.com/quic-go/webtransport-go"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// generateTestTLSCert creates a self-signed TLS certificate for testing.
|
|
func generateTestTLSCert(t *testing.T) tls.Certificate {
|
|
t.Helper()
|
|
|
|
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
|
require.NoError(t, err)
|
|
|
|
template := &x509.Certificate{
|
|
SerialNumber: big.NewInt(1),
|
|
Subject: pkix.Name{Organization: []string{"Test"}},
|
|
NotBefore: time.Now(),
|
|
NotAfter: time.Now().Add(10 * 365 * 24 * time.Hour),
|
|
KeyUsage: x509.KeyUsageDigitalSignature,
|
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
|
DNSNames: []string{"localhost"},
|
|
IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1), net.IPv6loopback},
|
|
}
|
|
|
|
certDER, err := x509.CreateCertificate(rand.Reader, template, template, &key.PublicKey, key)
|
|
require.NoError(t, err)
|
|
|
|
return tls.Certificate{
|
|
Certificate: [][]byte{certDER},
|
|
PrivateKey: key,
|
|
}
|
|
}
|
|
|
|
func TestWebTransportWithLogMiddleware(t *testing.T) {
|
|
cert := generateTestTLSCert(t)
|
|
|
|
wtServer := &webtransport.Server{
|
|
CheckOrigin: func(r *http.Request) bool { return true },
|
|
}
|
|
|
|
mux := http.NewServeMux()
|
|
mux.HandleFunc("/wt", func(w http.ResponseWriter, r *http.Request) {
|
|
session, err := wtServer.Upgrade(w, r)
|
|
if err != nil {
|
|
t.Logf("upgrade error: %v", err)
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return
|
|
}
|
|
stream, err := session.AcceptStream(r.Context())
|
|
if err != nil {
|
|
t.Logf("accept stream error: %v", err)
|
|
return
|
|
}
|
|
data, err := io.ReadAll(stream)
|
|
if err != nil {
|
|
t.Logf("read error: %v", err)
|
|
return
|
|
}
|
|
_, _ = stream.Write(data)
|
|
_ = stream.Close()
|
|
})
|
|
|
|
// Wrap with LogRequest middleware — this is the key part under test.
|
|
server := &http3.Server{
|
|
TLSConfig: &tls.Config{
|
|
Certificates: []tls.Certificate{cert},
|
|
NextProtos: []string{http3.NextProtoH3},
|
|
},
|
|
Handler: middleware.LogRequest(mux),
|
|
}
|
|
webtransport.ConfigureHTTP3Server(server)
|
|
wtServer.H3 = server
|
|
|
|
udpAddr, err := net.ResolveUDPAddr("udp", "localhost:0")
|
|
require.NoError(t, err)
|
|
udpConn, err := net.ListenUDP("udp", udpAddr)
|
|
require.NoError(t, err)
|
|
port := udpConn.LocalAddr().(*net.UDPAddr).Port
|
|
|
|
servErr := make(chan error, 1)
|
|
go func() { servErr <- wtServer.Serve(udpConn) }()
|
|
defer func() {
|
|
require.NoError(t, wtServer.Close())
|
|
<-servErr
|
|
}()
|
|
|
|
d := webtransport.Transport{
|
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
|
QUICConfig: &quic.Config{EnableDatagrams: true, EnableStreamResetPartialDelivery: true},
|
|
}
|
|
defer func() {
|
|
_ = d.Close()
|
|
}()
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
|
|
rsp, session, err := d.Dial(ctx, fmt.Sprintf("https://localhost:%d/wt", port), nil)
|
|
require.NoError(t, err)
|
|
require.Equal(t, http.StatusOK, rsp.StatusCode)
|
|
defer func() {
|
|
_ = session.CloseWithError(0, "")
|
|
}()
|
|
|
|
stream, err := session.OpenStream()
|
|
require.NoError(t, err)
|
|
_ = stream.SetDeadline(time.Now().Add(5 * time.Second))
|
|
|
|
msg := []byte("hello webtransport")
|
|
_, err = stream.Write(msg)
|
|
require.NoError(t, err)
|
|
require.NoError(t, stream.Close())
|
|
|
|
reply, err := io.ReadAll(stream)
|
|
require.NoError(t, err)
|
|
require.Equal(t, msg, reply)
|
|
}
|