mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-23 22:27:38 -05:00
proxy: websocket proxy exits immediately if backend is shutdown (#1869)
Signed-off-by: Tw <tw19881113@gmail.com>
This commit is contained in:
parent
84a2f8e89e
commit
e377eeff50
2 changed files with 47 additions and 2 deletions
|
@ -304,6 +304,40 @@ func TestWebSocketReverseProxyNonHijackerPanic(t *testing.T) {
|
|||
p.ServeHTTP(nonHijacker, r)
|
||||
}
|
||||
|
||||
func TestWebSocketReverseProxyBackendShutDown(t *testing.T) {
|
||||
shutdown := make(chan struct{})
|
||||
backend := httptest.NewServer(websocket.Handler(func(ws *websocket.Conn) {
|
||||
shutdown <- struct{}{}
|
||||
}))
|
||||
defer backend.Close()
|
||||
|
||||
go func() {
|
||||
<-shutdown
|
||||
backend.Close()
|
||||
}()
|
||||
|
||||
// Get proxy to use for the test
|
||||
p := newWebSocketTestProxy(backend.URL, false)
|
||||
backendProxy := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
p.ServeHTTP(w, r)
|
||||
}))
|
||||
defer backendProxy.Close()
|
||||
|
||||
// Set up WebSocket client
|
||||
url := strings.Replace(backendProxy.URL, "http://", "ws://", 1)
|
||||
ws, err := websocket.Dial(url, "", backendProxy.URL)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer ws.Close()
|
||||
|
||||
var actualMsg string
|
||||
if rcvErr := websocket.Message.Receive(ws, &actualMsg); rcvErr == nil {
|
||||
t.Errorf("we don't get backend shutdown notification")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWebSocketReverseProxyServeHTTPHandler(t *testing.T) {
|
||||
// No-op websocket backend simply allows the WS connection to be
|
||||
// accepted then it will be immediately closed. Perfect for testing.
|
||||
|
|
|
@ -320,8 +320,13 @@ func (rp *ReverseProxy) ServeHTTP(rw http.ResponseWriter, outreq *http.Request,
|
|||
}
|
||||
defer backendConn.Close()
|
||||
|
||||
proxyDone := make(chan struct{}, 2)
|
||||
|
||||
// Proxy backend -> frontend.
|
||||
go pooledIoCopy(conn, backendConn)
|
||||
go func() {
|
||||
pooledIoCopy(conn, backendConn)
|
||||
proxyDone <- struct{}{}
|
||||
}()
|
||||
|
||||
// Proxy frontend -> backend.
|
||||
//
|
||||
|
@ -336,7 +341,13 @@ func (rp *ReverseProxy) ServeHTTP(rw http.ResponseWriter, outreq *http.Request,
|
|||
backendConn.Write(rbuf)
|
||||
}
|
||||
}
|
||||
go func() {
|
||||
pooledIoCopy(backendConn, conn)
|
||||
proxyDone <- struct{}{}
|
||||
}()
|
||||
|
||||
// If one side is done, we are done.
|
||||
<-proxyDone
|
||||
} else {
|
||||
// NOTE:
|
||||
// Closing the Body involves acquiring a mutex, which is a
|
||||
|
|
Loading…
Reference in a new issue