@marcel91200 / caddy Mirror · read-only / commits / b40cacf5
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 12, 14:30 UTC

reverseproxy: Wait for both ends of websocket to close (#6175)

WeidiDeng committed Apr 16, 2024 at 01:37 UTC b40cacf5ce8f6a190a002fa44e973f1aa5bac2b0
2 files changed +9 -3
modules/caddyhttp/reverseproxy/reverseproxy.go
+3 -1
@@ -922,7 +922,9 @@ func (h *Handler) finalizeResponse(
922 ) error {
923 // deal with 101 Switching Protocols responses: (WebSocket, h2c, etc)
924 if res.StatusCode == http.StatusSwitchingProtocols {
925 - h.handleUpgradeResponse(logger, rw, req, res)
925 + var wg sync.WaitGroup
926 + h.handleUpgradeResponse(logger, &wg, rw, req, res)
927 + wg.Wait()
928 return nil
929 }
930
modules/caddyhttp/reverseproxy/streaming.go
+6 -2
@@ -34,7 +34,7 @@ import (
34 "golang.org/x/net/http/httpguts"
35 )
36
37 -func (h *Handler) handleUpgradeResponse(logger *zap.Logger, rw http.ResponseWriter, req *http.Request, res *http.Response) {
37 +func (h *Handler) handleUpgradeResponse(logger *zap.Logger, wg *sync.WaitGroup, rw http.ResponseWriter, req *http.Request, res *http.Response) {
38 reqUpType := upgradeType(req.Header)
39 resUpType := upgradeType(res.Header)
40
@@ -121,7 +121,7 @@ func (h *Handler) handleUpgradeResponse(logger *zap.Logger, rw http.ResponseWrit
121 defer deleteFrontConn()
122 defer deleteBackConn()
123
124 - spc := switchProtocolCopier{user: conn, backend: backConn}
124 + spc := switchProtocolCopier{user: conn, backend: backConn, wg: wg}
125
126 // setup the timeout if requested
127 var timeoutc <-chan time.Time
@@ -132,6 +132,7 @@ func (h *Handler) handleUpgradeResponse(logger *zap.Logger, rw http.ResponseWrit
132 }
133
134 errc := make(chan error, 1)
135 + wg.Add(2)
136 go spc.copyToBackend(errc)
137 go spc.copyFromBackend(errc)
138 select {
@@ -529,16 +530,19 @@ func (m *maxLatencyWriter) stop() {
530 // forth have nice names in stacks.
531 type switchProtocolCopier struct {
532 user, backend io.ReadWriteCloser
533 + wg *sync.WaitGroup
534 }
535
536 func (c switchProtocolCopier) copyFromBackend(errc chan<- error) {
537 _, err := io.Copy(c.user, c.backend)
538 errc <- err
539 + c.wg.Done()
540 }
541
542 func (c switchProtocolCopier) copyToBackend(errc chan<- error) {
543 _, err := io.Copy(c.backend, c.user)
544 errc <- err
545 + c.wg.Done()
546 }
547
548 var streamingBufPool = sync.Pool{