diff options
| author | Adnan Maolood <[email protected]> | 2021-02-24 19:22:26 -0500 |
|---|---|---|
| committer | Adnan Maolood <[email protected]> | 2021-02-24 19:25:52 -0500 |
| commit | 21ad3a2deddd233ed9004c042f67c6ebb1659523 (patch) | |
| tree | d2bb872b972015419968a6da308dca63af1d78a4 /server.go | |
| parent | Update examples/client.go (diff) | |
| download | go-gemini-21ad3a2deddd233ed9004c042f67c6ebb1659523.tar.xz go-gemini-21ad3a2deddd233ed9004c042f67c6ebb1659523.zip | |
server: Disallow ServeConn usage after Shutdownv0.1.17
Diffstat (limited to 'server.go')
| -rw-r--r-- | server.go | 21 |
1 files changed, 13 insertions, 8 deletions
@@ -282,14 +282,17 @@ func (srv *Server) serve(ctx context.Context, l net.Listener) error { return err } tempDelay = 0 - go srv.ServeConn(ctx, rw) + go srv.serveConn(ctx, rw, false) } } -func (srv *Server) trackConn(conn *net.Conn, cancel context.CancelFunc) bool { +func (srv *Server) trackConn(conn *net.Conn, cancel context.CancelFunc, external bool) bool { srv.mu.Lock() defer srv.mu.Unlock() - if srv.closed && !srv.shutdown { + // Reject the connection under the following conditions: + // - Shutdown or Close has been called and conn is external (from ServeConn) + // - Close (not Shutdown) has been called and conn is internal (from Serve) + if srv.closed && (external || !srv.shutdown) { return false } if srv.conns == nil { @@ -309,15 +312,17 @@ func (srv *Server) deleteConn(conn *net.Conn) { // It closes the connection when the response has been completed. // If the provided context expires before the response has completed, // ServeConn closes the connection and returns the context's error. -// -// Note that ServeConn can be used during a Shutdown. func (srv *Server) ServeConn(ctx context.Context, conn net.Conn) error { + return srv.serveConn(ctx, conn, true) +} + +func (srv *Server) serveConn(ctx context.Context, conn net.Conn, external bool) error { defer conn.Close() ctx, cancel := context.WithCancel(ctx) defer cancel() - if !srv.trackConn(&conn, cancel) { + if !srv.trackConn(&conn, cancel, external) { return context.Canceled } defer srv.tryCloseDone() @@ -332,7 +337,7 @@ func (srv *Server) ServeConn(ctx context.Context, conn net.Conn) error { errch := make(chan error, 1) go func() { - errch <- srv.serveConn(ctx, conn) + errch <- srv.goServeConn(ctx, conn) }() select { @@ -343,7 +348,7 @@ func (srv *Server) ServeConn(ctx context.Context, conn net.Conn) error { } } -func (srv *Server) serveConn(ctx context.Context, conn net.Conn) error { +func (srv *Server) goServeConn(ctx context.Context, conn net.Conn) error { ctx, cancel := context.WithCancel(ctx) done := ctx.Done() cw := &contextWriter{ |