interop: simplify API of http09.Server (#4651)

Removes the ListenAndServe method in favor of a ServeListener method.
This commit is contained in:
Marten Seemann
2024-08-31 13:13:20 +08:00
committed by GitHub
parent 7c3544ca34
commit 0b32adc145
4 changed files with 37 additions and 67 deletions

View File

@@ -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,

View File

@@ -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())
})

View File

@@ -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 {

View File

@@ -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 {