mirror of https://github.com/grpc/grpc-go.git
Simplify server setup when testing the http.Handler-based server transport
This simplifies the code that's used for wiring up the http.Handler-based transport for testing. It's not used outside of tests. http2.Server.ServeConn was added somewhat recently for other reasons and I just realized it would simplify this code as well.
This commit is contained in:
parent
89f694edb4
commit
18b2da6250
55
server.go
55
server.go
|
@ -247,7 +247,6 @@ func (s *Server) Serve(lis net.Listener) error {
|
||||||
delete(s.lis, lis)
|
delete(s.lis, lis)
|
||||||
s.mu.Unlock()
|
s.mu.Unlock()
|
||||||
}()
|
}()
|
||||||
listenerAddr := lis.Addr()
|
|
||||||
for {
|
for {
|
||||||
rawConn, err := lis.Accept()
|
rawConn, err := lis.Accept()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -258,13 +257,13 @@ func (s *Server) Serve(lis net.Listener) error {
|
||||||
}
|
}
|
||||||
// Start a new goroutine to deal with rawConn
|
// Start a new goroutine to deal with rawConn
|
||||||
// so we don't stall this Accept loop goroutine.
|
// so we don't stall this Accept loop goroutine.
|
||||||
go s.handleRawConn(listenerAddr, rawConn)
|
go s.handleRawConn(rawConn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleRawConn is run in its own goroutine and handles a just-accepted
|
// handleRawConn is run in its own goroutine and handles a just-accepted
|
||||||
// connection that has not had any I/O performed on it yet.
|
// connection that has not had any I/O performed on it yet.
|
||||||
func (s *Server) handleRawConn(listenerAddr net.Addr, rawConn net.Conn) {
|
func (s *Server) handleRawConn(rawConn net.Conn) {
|
||||||
conn, authInfo, err := s.useTransportAuthenticator(rawConn)
|
conn, authInfo, err := s.useTransportAuthenticator(rawConn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
|
@ -284,7 +283,7 @@ func (s *Server) handleRawConn(listenerAddr net.Addr, rawConn net.Conn) {
|
||||||
s.mu.Unlock()
|
s.mu.Unlock()
|
||||||
|
|
||||||
if s.opts.useHandlerImpl {
|
if s.opts.useHandlerImpl {
|
||||||
s.serveUsingHandler(listenerAddr, conn)
|
s.serveUsingHandler(conn)
|
||||||
} else {
|
} else {
|
||||||
s.serveNewHTTP2Transport(conn, authInfo)
|
s.serveNewHTTP2Transport(conn, authInfo)
|
||||||
}
|
}
|
||||||
|
@ -340,29 +339,18 @@ var _ http.Handler = (*Server)(nil)
|
||||||
// method as one of the environment types.
|
// method as one of the environment types.
|
||||||
//
|
//
|
||||||
// conn is the *tls.Conn that's already been authenticated.
|
// conn is the *tls.Conn that's already been authenticated.
|
||||||
func (s *Server) serveUsingHandler(listenerAddr net.Addr, conn net.Conn) {
|
func (s *Server) serveUsingHandler(conn net.Conn) {
|
||||||
if !s.addConn(conn) {
|
if !s.addConn(conn) {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer s.removeConn(conn)
|
defer s.removeConn(conn)
|
||||||
connDone := make(chan struct{})
|
h2s := &http2.Server{
|
||||||
hs := &http.Server{
|
|
||||||
Handler: s,
|
|
||||||
ConnState: func(c net.Conn, cs http.ConnState) {
|
|
||||||
if cs == http.StateClosed {
|
|
||||||
close(connDone)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
if err := http2.ConfigureServer(hs, &http2.Server{
|
|
||||||
MaxConcurrentStreams: s.opts.maxConcurrentStreams,
|
MaxConcurrentStreams: s.opts.maxConcurrentStreams,
|
||||||
}); err != nil {
|
|
||||||
grpclog.Fatalf("grpc: http2.ConfigureServer: %v", err)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
hs.Serve(&singleConnListener{addr: listenerAddr, conn: conn})
|
h2s.ServeConn(conn, &http2.ServeConnOpts{
|
||||||
<-connDone
|
Handler: s,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -754,30 +742,3 @@ func SetTrailer(ctx context.Context, md metadata.MD) error {
|
||||||
}
|
}
|
||||||
return stream.SetTrailer(md)
|
return stream.SetTrailer(md)
|
||||||
}
|
}
|
||||||
|
|
||||||
// singleConnListener is a net.Listener that yields a single conn.
|
|
||||||
type singleConnListener struct {
|
|
||||||
mu sync.Mutex
|
|
||||||
addr net.Addr
|
|
||||||
conn net.Conn // nil if done
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ln *singleConnListener) Addr() net.Addr { return ln.addr }
|
|
||||||
|
|
||||||
func (ln *singleConnListener) Close() error {
|
|
||||||
ln.mu.Lock()
|
|
||||||
defer ln.mu.Unlock()
|
|
||||||
ln.conn = nil
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ln *singleConnListener) Accept() (net.Conn, error) {
|
|
||||||
ln.mu.Lock()
|
|
||||||
defer ln.mu.Unlock()
|
|
||||||
c := ln.conn
|
|
||||||
if c == nil {
|
|
||||||
return nil, io.EOF
|
|
||||||
}
|
|
||||||
ln.conn = nil
|
|
||||||
return c, nil
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue