Skip to content

Commit

Permalink
reverseproxy: Fix hijack ordering which broke websockets (#5679)
Browse files Browse the repository at this point in the history
  • Loading branch information
WeidiDeng authored Aug 3, 2023
1 parent 4aa4f3a commit e2fc08b
Showing 1 changed file with 12 additions and 11 deletions.
23 changes: 12 additions & 11 deletions modules/caddyhttp/reverseproxy/streaming.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,25 @@ func (h *Handler) handleUpgradeResponse(logger *zap.Logger, rw http.ResponseWrit
return
}

// write header first, response headers should not be counted in size
// like the rest of handler chain.
copyHeader(rw.Header(), res.Header)
rw.WriteHeader(res.StatusCode)

logger.Debug("upgrading connection")

//nolint:bodyclose
conn, brw, hijackErr := http.NewResponseController(rw).Hijack()
if errors.Is(hijackErr, http.ErrNotSupported) {
h.logger.Sugar().Errorf("can't switch protocols using non-Hijacker ResponseWriter type %T", rw)
return
}

if hijackErr != nil {
h.logger.Error("hijack failed on protocol switch", zap.Error(hijackErr))
return
}

// adopted from https://github.com/golang/go/commit/8bcf2834afdf6a1f7937390903a41518715ef6f5
backConnCloseCh := make(chan struct{})
go func() {
Expand All @@ -78,17 +90,6 @@ func (h *Handler) handleUpgradeResponse(logger *zap.Logger, rw http.ResponseWrit
}()
defer close(backConnCloseCh)

// write header first, response headers should not be counted in size
// like the rest of handler chain.
copyHeader(rw.Header(), res.Header)
rw.WriteHeader(res.StatusCode)

logger.Debug("upgrading connection")
if hijackErr != nil {
h.logger.Error("hijack failed on protocol switch", zap.Error(hijackErr))
return
}

start := time.Now()
defer func() {
conn.Close()
Expand Down

0 comments on commit e2fc08b

Please sign in to comment.