forked from quic-go/quic-go
dependency-inject quic.Listen and quic.ListenAddr in h2quic.Server
This commit is contained in:
@@ -29,6 +29,12 @@ type remoteCloser interface {
|
||||
CloseRemote(protocol.ByteCount)
|
||||
}
|
||||
|
||||
// allows mocking of quic.Listen and quic.ListenAddr
|
||||
var (
|
||||
quicListen = quic.Listen
|
||||
quicListenAddr = quic.ListenAddr
|
||||
)
|
||||
|
||||
// Server is a HTTP2 server listening for QUIC connections.
|
||||
type Server struct {
|
||||
*http.Server
|
||||
@@ -90,9 +96,9 @@ func (s *Server) serveImpl(tlsConfig *tls.Config, conn net.PacketConn) error {
|
||||
var ln quic.Listener
|
||||
var err error
|
||||
if conn == nil {
|
||||
ln, err = quic.ListenAddr(s.Addr, tlsConfig, &config)
|
||||
ln, err = quicListenAddr(s.Addr, tlsConfig, &config)
|
||||
} else {
|
||||
ln, err = quic.Listen(conn, tlsConfig, &config)
|
||||
ln, err = quicListen(conn, tlsConfig, &config)
|
||||
}
|
||||
if err != nil {
|
||||
s.listenerMutex.Unlock()
|
||||
|
||||
@@ -2,13 +2,12 @@ package h2quic
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"runtime"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/http2"
|
||||
@@ -66,9 +65,10 @@ func (s *mockSession) WaitUntilClosed() { panic("not implemented") }
|
||||
|
||||
var _ = Describe("H2 server", func() {
|
||||
var (
|
||||
s *Server
|
||||
session *mockSession
|
||||
dataStream *mockStream
|
||||
s *Server
|
||||
session *mockSession
|
||||
dataStream *mockStream
|
||||
origQuicListenAddr = quicListenAddr
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
@@ -80,6 +80,11 @@ var _ = Describe("H2 server", func() {
|
||||
dataStream = newMockStream(0)
|
||||
close(dataStream.unblockRead)
|
||||
session = &mockSession{dataStream: dataStream}
|
||||
origQuicListenAddr = quicListenAddr
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
quicListenAddr = origQuicListenAddr
|
||||
})
|
||||
|
||||
Context("handling requests", func() {
|
||||
@@ -399,7 +404,6 @@ var _ = Describe("H2 server", func() {
|
||||
Expect(err).To(MatchError("ListenAndServe may only be called once"))
|
||||
err = s.Close()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
}, 0.5)
|
||||
})
|
||||
|
||||
@@ -436,31 +440,13 @@ var _ = Describe("H2 server", func() {
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("at least errors in global ListenAndServeQUIC", func() {
|
||||
// It's quite hard to test this, since we cannot properly shutdown the server
|
||||
// once it's started. So, we open a socket on the same port before the test,
|
||||
// so that ListenAndServeQUIC definitely fails. This way we know it at least
|
||||
// created a socket on the proper address :)
|
||||
const addr = "127.0.0.1:4826"
|
||||
udpAddr, err := net.ResolveUDPAddr("udp", addr)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
c, err := net.ListenUDP("udp", udpAddr)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
defer c.Close()
|
||||
fullpem, privkey := testdata.GetCertificatePaths()
|
||||
err = ListenAndServeQUIC(addr, fullpem, privkey, nil)
|
||||
// Check that it's an EADDRINUSE
|
||||
Expect(err).ToNot(BeNil())
|
||||
opErr, ok := err.(*net.OpError)
|
||||
Expect(ok).To(BeTrue())
|
||||
syscallErr, ok := opErr.Err.(*os.SyscallError)
|
||||
Expect(ok).To(BeTrue())
|
||||
if runtime.GOOS == "windows" {
|
||||
// for some reason, Windows return a different error number, corresponding to an WSAEADDRINUSE error
|
||||
// see https://msdn.microsoft.com/en-us/library/windows/desktop/ms681391(v=vs.85).aspx
|
||||
Expect(syscallErr.Err).To(Equal(syscall.Errno(0x2740)))
|
||||
} else {
|
||||
Expect(syscallErr.Err).To(MatchError(syscall.EADDRINUSE))
|
||||
It("errors when listening fails", func() {
|
||||
testErr := errors.New("listen error")
|
||||
quicListenAddr = func(addr string, tlsConf *tls.Config, config *quic.Config) (quic.Listener, error) {
|
||||
return nil, testErr
|
||||
}
|
||||
fullpem, privkey := testdata.GetCertificatePaths()
|
||||
err := ListenAndServeQUIC("", fullpem, privkey, nil)
|
||||
Expect(err).To(MatchError(testErr))
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user