mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-11-04 03:27:23 -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
					
				@ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user