forked from quic-go/quic-go
add a h2quic.ListenAndServe method that listens on TCP in parallel
fixes #327
This commit is contained in:
@@ -257,3 +257,79 @@ func ListenAndServeQUIC(addr, certFile, keyFile string, handler http.Handler) er
|
|||||||
}
|
}
|
||||||
return server.ListenAndServeTLS(certFile, keyFile)
|
return server.ListenAndServeTLS(certFile, keyFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListenAndServe listens on the given network address for both, TLS and QUIC
|
||||||
|
// connetions in parallel. It returns if one of the two returns an error.
|
||||||
|
// http.DefaultServeMux is used when handler is nil.
|
||||||
|
// The correct Alt-Svc headers for QUIC are set.
|
||||||
|
func ListenAndServe(addr, certFile, keyFile string, handler http.Handler) error {
|
||||||
|
// Load certs
|
||||||
|
var err error
|
||||||
|
certs := make([]tls.Certificate, 1)
|
||||||
|
certs[0], err = tls.LoadX509KeyPair(certFile, keyFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// We currently only use the cert-related stuff from tls.Config,
|
||||||
|
// so we don't need to make a full copy.
|
||||||
|
config := &tls.Config{
|
||||||
|
Certificates: certs,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open the listeners
|
||||||
|
udpAddr, err := net.ResolveUDPAddr("udp", addr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
udpConn, err := net.ListenUDP("udp", udpAddr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer udpConn.Close()
|
||||||
|
|
||||||
|
tcpAddr, err := net.ResolveTCPAddr("tcp", addr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
tcpConn, err := net.ListenTCP("tcp", tcpAddr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer tcpConn.Close()
|
||||||
|
|
||||||
|
// Start the servers
|
||||||
|
httpServer := &http.Server{
|
||||||
|
Addr: addr,
|
||||||
|
TLSConfig: config,
|
||||||
|
}
|
||||||
|
|
||||||
|
quicServer := &Server{
|
||||||
|
Server: httpServer,
|
||||||
|
}
|
||||||
|
|
||||||
|
if handler == nil {
|
||||||
|
handler = http.DefaultServeMux
|
||||||
|
}
|
||||||
|
httpServer.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
quicServer.SetQuicHeaders(w.Header())
|
||||||
|
handler.ServeHTTP(w, r)
|
||||||
|
})
|
||||||
|
|
||||||
|
hErr := make(chan error)
|
||||||
|
qErr := make(chan error)
|
||||||
|
go func() {
|
||||||
|
hErr <- httpServer.Serve(tcpConn)
|
||||||
|
}()
|
||||||
|
go func() {
|
||||||
|
qErr <- quicServer.Serve(udpConn)
|
||||||
|
}()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case err := <-hErr:
|
||||||
|
quicServer.Close()
|
||||||
|
return err
|
||||||
|
case err := <-qErr:
|
||||||
|
// Cannot close the HTTP server or wait for requests to complete properly :/
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user