Skip to content

Commit 59fb168

Browse files
Revert "Merge pull request #2578 from keboola/pepa/PAT-1538_e2bStreamlit"
This reverts commit ee88991, reversing changes made to a40cb25.
1 parent ceaa0b1 commit 59fb168

2 files changed

Lines changed: 64 additions & 0 deletions

File tree

internal/pkg/service/appsproxy/proxy/apphandler/upstream/upstream.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,27 @@ func (u *AppUpstream) newProxy(timeout time.Duration) *chain.Chain {
234234
func (u *AppUpstream) newWebsocketProxy(timeout time.Duration) *chain.Chain {
235235
proxy := u.newReverseProxy()
236236

237+
// ******************************************************************************
238+
// TEMPORARY WORKAROUND — remove once Streamlit apps are configured with
239+
// STREAMLIT_BROWSER_SERVER_ADDRESS / STREAMLIT_BROWSER_SERVER_PORT env vars.
240+
//
241+
// Streamlit (Tornado) checks WebSocket origin by comparing the Origin header
242+
// against the Host header. Since apps-proxy rewrites Host to the upstream
243+
// hostname (required for LB routing), Origin (the public domain set by the
244+
// browser) no longer matches and Tornado rejects the connection with 403.
245+
//
246+
// Rewriting Origin to the upstream hostname makes the request look like a
247+
// direct browser connection, which is what every framework expects.
248+
// ******************************************************************************
249+
if u.target != nil {
250+
upstreamOrigin := u.target.Scheme + "://" + u.target.Host
251+
origRewrite := proxy.Rewrite
252+
proxy.Rewrite = func(r *httputil.ProxyRequest) {
253+
origRewrite(r)
254+
r.Out.Header.Set("Origin", upstreamOrigin)
255+
}
256+
}
257+
237258
return chain.
238259
New(chain.HandlerFunc(func(w http.ResponseWriter, req *http.Request) error {
239260
ctx := ctxattr.ContextWith(req.Context(), attribute.Bool(attrWebsocket, true))

internal/pkg/service/appsproxy/proxy/proxy_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,49 @@ func TestAppProxyRouter(t *testing.T) {
473473

474474
// X-Forwarded-For contains the client IP.
475475
assert.NotEmpty(t, appRequest.Header.Get("X-Forwarded-For"))
476+
477+
// Origin is rewritten to the upstream hostname (Streamlit/Tornado workaround).
478+
assert.Equal(t, "http://"+appServer.Listener.Addr().String(), appRequest.Header.Get("Origin"))
479+
},
480+
expectedNotifications: map[string]int{
481+
"123": 1,
482+
},
483+
},
484+
{
485+
// Streamlit (Tornado) rejects WebSocket connections when Origin does not match Host.
486+
// apps-proxy rewrites Host to the upstream hostname for LB routing, so Origin
487+
// (set by the browser to the public domain) would mismatch.
488+
// Verify the temporary workaround: Origin is rewritten to the upstream hostname.
489+
name: "websocket-origin-rewrite-streamlit-workaround",
490+
run: func(t *testing.T, client *http.Client, m []*mockoidc.MockOIDC, appServer *testutil.AppServer, service *testutil.DataAppsAPI, fakeClient *k8sfake.FakeDynamicClient, watcher *k8sapp.StateWatcher) {
491+
ctx, cancel := context.WithTimeout(t.Context(), time.Minute)
492+
defer cancel()
493+
494+
c, _, err := websocket.Dial(
495+
ctx,
496+
"wss://public-123.hub.keboola.local/ws",
497+
&websocket.DialOptions{
498+
HTTPClient: client,
499+
// Simulate browser setting Origin to the public domain.
500+
HTTPHeader: http.Header{
501+
"Origin": []string{"https://public-123.hub.keboola.local"},
502+
},
503+
},
504+
)
505+
require.NoError(t, err)
506+
507+
var v any
508+
err = wsjson.Read(ctx, c, &v)
509+
require.NoError(t, err)
510+
assert.Equal(t, "Hello websocket", v)
511+
require.NoError(t, c.Close(websocket.StatusNormalClosure, ""))
512+
513+
require.Len(t, *appServer.Requests, 1)
514+
appRequest := (*appServer.Requests)[0]
515+
516+
// Origin must be rewritten to the upstream hostname so Tornado's
517+
// check_origin() sees Origin == Host and accepts the connection.
518+
assert.Equal(t, "http://"+appServer.Listener.Addr().String(), appRequest.Header.Get("Origin"))
476519
},
477520
expectedNotifications: map[string]int{
478521
"123": 1,

0 commit comments

Comments
 (0)