From c343177a238c27e86cdc1ebd42960d40ad504a6f Mon Sep 17 00:00:00 2001 From: Colin Adler Date: Mon, 17 Oct 2022 11:04:12 -0500 Subject: [PATCH] fix: chrome requests hanging over port-forward Fixes https://github.com/coder/coder/issues/3733 --- agent/agent.go | 16 +++++++++++++--- cli/portforward.go | 9 ++++++--- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/agent/agent.go b/agent/agent.go index f7c5598b7b710..ffaf2ed454c66 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -879,12 +879,22 @@ func (r *reconnectingPTY) Close() { // after one or both of them are done writing. If the context is canceled, both // of the connections will be closed. func Bicopy(ctx context.Context, c1, c2 io.ReadWriteCloser) { - defer c1.Close() - defer c2.Close() + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + defer func() { + _ = c1.Close() + _ = c2.Close() + }() var wg sync.WaitGroup copyFunc := func(dst io.WriteCloser, src io.Reader) { - defer wg.Done() + defer func() { + wg.Done() + // If one side of the copy fails, ensure the other one exits as + // well. + cancel() + }() _, _ = io.Copy(dst, src) } diff --git a/cli/portforward.go b/cli/portforward.go index 5a6f4391dd897..911e8fb5208d7 100644 --- a/cli/portforward.go +++ b/cli/portforward.go @@ -138,8 +138,7 @@ func portForward() *cobra.Command { case <-ctx.Done(): closeErr = ctx.Err() case <-sigs: - _, _ = fmt.Fprintln(cmd.OutOrStderr(), "Received signal, closing all listeners and active connections") - closeErr = xerrors.New("signal received") + _, _ = fmt.Fprintln(cmd.OutOrStderr(), "\nReceived signal, closing all listeners and active connections") } cancel() @@ -213,7 +212,11 @@ func listenAndPortForward(ctx context.Context, cmd *cobra.Command, conn *codersd for { netConn, err := l.Accept() if err != nil { - _, _ = fmt.Fprintf(cmd.OutOrStderr(), "Error accepting connection from '%v://%v': %+v\n", spec.listenNetwork, spec.listenAddress, err) + // Silently ignore net.ErrClosed errors. + if xerrors.Is(err, net.ErrClosed) { + return + } + _, _ = fmt.Fprintf(cmd.OutOrStderr(), "Error accepting connection from '%v://%v': %v\n", spec.listenNetwork, spec.listenAddress, err) _, _ = fmt.Fprintln(cmd.OutOrStderr(), "Killing listener") return }