From 0b32adc145cf4241234d0a0d6f0297c320aa0eaf Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sat, 31 Aug 2024 13:13:20 +0800 Subject: [PATCH] interop: simplify API of http09.Server (#4651) Removes the ListenAndServe method in favor of a ServeListener method. --- interop/http09/client.go | 2 +- interop/http09/http_test.go | 30 ++++++++++++-------------- interop/http09/server.go | 43 ++----------------------------------- interop/server/main.go | 29 +++++++++++++++++-------- 4 files changed, 37 insertions(+), 67 deletions(-) diff --git a/interop/http09/client.go b/interop/http09/client.go index b6de79ef..bb3f0d70 100644 --- a/interop/http09/client.go +++ b/interop/http09/client.go @@ -52,7 +52,7 @@ func (r *RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { if r.TLSClientConfig != nil { tlsConf = r.TLSClientConfig.Clone() } - tlsConf.NextProtos = []string{h09alpn} + tlsConf.NextProtos = []string{NextProto} c = &client{ hostname: hostname, tlsConf: tlsConf, diff --git a/interop/http09/http_test.go b/interop/http09/http_test.go index 03f39263..fb0e5e06 100644 --- a/interop/http09/http_test.go +++ b/interop/http09/http_test.go @@ -7,7 +7,6 @@ import ( "net" "net/http" "net/http/httptest" - "time" "github.com/quic-go/quic-go" "github.com/quic-go/quic-go/internal/testdata" @@ -18,9 +17,9 @@ import ( var _ = Describe("HTTP 0.9 integration tests", func() { var ( - server *Server - saddr net.Addr - done chan struct{} + ln *quic.EarlyListener + saddr net.Addr + done chan struct{} ) http.HandleFunc("/helloworld", func(w http.ResponseWriter, r *http.Request) { @@ -28,28 +27,27 @@ var _ = Describe("HTTP 0.9 integration tests", func() { }) BeforeEach(func() { - server = &Server{ - Server: &http.Server{TLSConfig: testdata.GetTLSConfig()}, + server := &Server{ + Server: &http.Server{}, } + conn, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: 0}) + Expect(err).ToNot(HaveOccurred()) + tr := &quic.Transport{Conn: conn} + tlsConf := testdata.GetTLSConfig() + tlsConf.NextProtos = []string{NextProto} + ln, err = tr.ListenEarly(tlsConf, &quic.Config{}) + Expect(err).ToNot(HaveOccurred()) done = make(chan struct{}) go func() { defer GinkgoRecover() defer close(done) - _ = server.ListenAndServe() + _ = server.ServeListener(ln) }() - var ln *quic.EarlyListener - Eventually(func() *quic.EarlyListener { - server.mutex.Lock() - defer server.mutex.Unlock() - ln = server.listener - return server.listener - }, 5*time.Second).ShouldNot(BeNil()) saddr = ln.Addr() - saddr.(*net.UDPAddr).IP = net.IP{127, 0, 0, 1} }) AfterEach(func() { - Expect(server.Close()).To(Succeed()) + Expect(ln.Close()).To(Succeed()) Eventually(done).Should(BeClosed()) }) diff --git a/interop/http09/server.go b/interop/http09/server.go index 7a1f30b8..9a6c7b32 100644 --- a/interop/http09/server.go +++ b/interop/http09/server.go @@ -5,17 +5,15 @@ import ( "errors" "io" "log" - "net" "net/http" "net/url" "runtime" "strings" - "sync" "github.com/quic-go/quic-go" ) -const h09alpn = "hq-interop" +const NextProto = "hq-interop" type responseWriter struct { io.Writer @@ -36,51 +34,14 @@ func (w *responseWriter) WriteHeader(int) {} // Server is a HTTP/0.9 server listening for QUIC connections. type Server struct { *http.Server - - ForceRetry bool - QuicConfig *quic.Config - - mutex sync.Mutex - listener *quic.EarlyListener -} - -// Close closes the server. -func (s *Server) Close() error { - s.mutex.Lock() - defer s.mutex.Unlock() - - return s.listener.Close() } // ListenAndServe listens and serves HTTP/0.9 over QUIC. -func (s *Server) ListenAndServe() error { +func (s *Server) ServeListener(ln *quic.EarlyListener) error { if s.Server == nil { return errors.New("use of http3.Server without http.Server") } - udpAddr, err := net.ResolveUDPAddr("udp", s.Addr) - if err != nil { - return err - } - conn, err := net.ListenUDP("udp", udpAddr) - if err != nil { - return err - } - - tlsConf := s.TLSConfig.Clone() - tlsConf.NextProtos = []string{h09alpn} - tr := quic.Transport{Conn: conn} - if s.ForceRetry { - tr.VerifySourceAddress = func(net.Addr) bool { return true } - } - ln, err := tr.ListenEarly(tlsConf, s.QuicConfig) - if err != nil { - return err - } - s.mutex.Lock() - s.listener = ln - s.mutex.Unlock() - for { conn, err := ln.Accept(context.Background()) if err != nil { diff --git a/interop/server/main.go b/interop/server/main.go index fee8aaeb..018d9cf8 100644 --- a/interop/server/main.go +++ b/interop/server/main.go @@ -4,6 +4,7 @@ import ( "crypto/tls" "fmt" "log" + "net" "net/http" "os" @@ -71,16 +72,26 @@ func main() { } func runHTTP09Server(quicConf *quic.Config, forceRetry bool) error { - server := http09.Server{ - Server: &http.Server{ - Addr: ":443", - TLSConfig: tlsConf, - }, - ForceRetry: forceRetry, - QuicConfig: quicConf, - } http.DefaultServeMux.Handle("/", http.FileServer(http.Dir("/www"))) - return server.ListenAndServe() + server := http09.Server{} + + udpAddr, err := net.ResolveUDPAddr("udp", ":443") + if err != nil { + return err + } + conn, err := net.ListenUDP("udp", udpAddr) + if err != nil { + return err + } + tr := &quic.Transport{ + Conn: conn, + VerifySourceAddress: func(net.Addr) bool { return forceRetry }, + } + ln, err := tr.ListenEarly(tlsConf, quicConf) + if err != nil { + return err + } + return server.ServeListener(ln) } func runHTTP3Server(quicConf *quic.Config) error {