feat: enhance WebSocket support by adding X-Forwarded headers and related tests

This commit is contained in:
GitHub Actions
2025-12-19 18:55:41 +00:00
parent ba3941c577
commit b79af10014
4 changed files with 3538 additions and 3334 deletions

View File

@@ -141,6 +141,12 @@ func ReverseProxyHandler(dial string, enableWS bool, application string) Handler
if enableWS {
setHeaders["Upgrade"] = []string{"{http.request.header.Upgrade}"}
setHeaders["Connection"] = []string{"{http.request.header.Connection}"}
// Add X-Forwarded headers for WebSocket proxy awareness
// Required by many apps (e.g., SignalR, FileFlows) to properly handle
// WebSocket connections behind a reverse proxy
setHeaders["X-Forwarded-Proto"] = []string{"{http.request.scheme}"}
setHeaders["X-Forwarded-Host"] = []string{"{http.request.host}"}
setHeaders["X-Real-IP"] = []string{"{http.request.remote.host}"}
}
// Application-specific headers for proper client IP forwarding

View File

@@ -41,3 +41,45 @@ func TestReverseProxyHandler_PlexAndOthers(t *testing.T) {
}
}
}
func TestReverseProxyHandler_WebSocketHeaders(t *testing.T) {
// Test: WebSocket enabled should include X-Forwarded headers
h := ReverseProxyHandler("app:8080", true, "none")
require.Equal(t, "reverse_proxy", h["handler"])
hdrs, ok := h["headers"].(map[string]interface{})
require.True(t, ok, "expected headers map when enableWS=true")
req, ok := hdrs["request"].(map[string]interface{})
require.True(t, ok, "expected request headers")
set, ok := req["set"].(map[string][]string)
require.True(t, ok, "expected set headers")
// Verify WebSocket passthrough headers
require.Contains(t, set, "Upgrade", "Upgrade header should be set for WebSocket")
require.Equal(t, []string{"{http.request.header.Upgrade}"}, set["Upgrade"])
require.Contains(t, set, "Connection", "Connection header should be set for WebSocket")
require.Equal(t, []string{"{http.request.header.Connection}"}, set["Connection"])
// Verify X-Forwarded headers for proxy awareness
require.Contains(t, set, "X-Forwarded-Proto", "X-Forwarded-Proto should be set for WebSocket")
require.Equal(t, []string{"{http.request.scheme}"}, set["X-Forwarded-Proto"])
require.Contains(t, set, "X-Forwarded-Host", "X-Forwarded-Host should be set for WebSocket")
require.Equal(t, []string{"{http.request.host}"}, set["X-Forwarded-Host"])
require.Contains(t, set, "X-Real-IP", "X-Real-IP should be set for WebSocket")
require.Equal(t, []string{"{http.request.remote.host}"}, set["X-Real-IP"])
}
func TestReverseProxyHandler_NoWebSocketNoForwardedHeaders(t *testing.T) {
// Test: WebSocket disabled with no application should NOT have X-Forwarded headers
h := ReverseProxyHandler("app:8080", false, "none")
require.Equal(t, "reverse_proxy", h["handler"])
// With enableWS=false and application="none", there should be no headers config
_, ok := h["headers"]
require.False(t, ok, "expected no headers when enableWS=false and application=none")
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff