diff --git a/lib/web/app/fragment.go b/lib/web/app/fragment.go index 6710a3c871ef9..27065ddd422b3 100644 --- a/lib/web/app/fragment.go +++ b/lib/web/app/fragment.go @@ -57,6 +57,7 @@ func (h *Handler) handleFragment(w http.ResponseWriter, r *http.Request, p httpr clusterName: q.Get("cluster"), publicAddr: q.Get("addr"), awsRole: q.Get("awsrole"), + path: q.Get("path"), stateToken: stateToken, } return h.redirectToLauncher(w, r, urlParams) diff --git a/lib/web/app/handler.go b/lib/web/app/handler.go index 3208247959985..588657916bab3 100644 --- a/lib/web/app/handler.go +++ b/lib/web/app/handler.go @@ -337,7 +337,7 @@ func HasName(r *http.Request, proxyPublicAddrs []utils.NetAddr) (string, bool) { u := url.URL{ Scheme: "https", Host: proxyPublicAddrs[0].String(), - Path: fmt.Sprintf("/web/launch/%v", raddr.Host()), + Path: fmt.Sprintf("/web/launch/%v?path=%v", raddr.Host(), r.URL.Path), } return u.String(), true } diff --git a/lib/web/app/handler_test.go b/lib/web/app/handler_test.go index 0a262a6164ff1..f63a5ab49fe02 100644 --- a/lib/web/app/handler_test.go +++ b/lib/web/app/handler_test.go @@ -103,6 +103,49 @@ func TestAuthPOST(t *testing.T) { } } +func TestHasName(t *testing.T) { + for _, test := range []struct { + desc string + addrs []string + reqHost string + reqURL string + expectedURL string + hasName bool + }{ + { + desc: "NOK - invalid host", + addrs: []string{"proxy.com"}, + reqURL: "badurl.com", + expectedURL: "", + hasName: false, + }, + { + desc: "OK - adds path", + addrs: []string{"proxy.com"}, + reqURL: "https://app1.proxy.com/foo", + expectedURL: "https://proxy.com/web/launch/app1.proxy.com%3Fpath=/foo", + hasName: true, + }, + { + desc: "OK - adds root path", + addrs: []string{"proxy.com"}, + reqURL: "https://app1.proxy.com/", + expectedURL: "https://proxy.com/web/launch/app1.proxy.com%3Fpath=/", + hasName: true, + }, + } { + t.Run(test.desc, func(t *testing.T) { + req, err := http.NewRequest(http.MethodGet, test.reqURL, nil) + require.NoError(t, err) + + addrs := utils.MustParseAddrList(test.addrs...) + u, ok := HasName(req, addrs) + require.Equal(t, test.expectedURL, u) + require.Equal(t, test.hasName, ok) + }) + } +} + func TestMatchApplicationServers(t *testing.T) { clusterName := "test-cluster" publicAddr := "app.example.com" diff --git a/lib/web/app/middleware.go b/lib/web/app/middleware.go index 9c7de342132bd..b7a572a0d1dfe 100644 --- a/lib/web/app/middleware.go +++ b/lib/web/app/middleware.go @@ -90,6 +90,9 @@ func (h *Handler) redirectToLauncher(w http.ResponseWriter, r *http.Request, p l if p.awsRole != "" { urlQuery.Add("awsrole", p.awsRole) } + if p.path != "" { + urlQuery.Add("path", p.path) + } u := url.URL{ Scheme: "https", @@ -106,6 +109,7 @@ type launcherURLParams struct { publicAddr string stateToken string awsRole string + path string } // makeRouterHandler creates a httprouter.Handle. diff --git a/lib/web/app/redirect.go b/lib/web/app/redirect.go index 98b02073f9ccb..5b66ee8db2ddf 100644 --- a/lib/web/app/redirect.go +++ b/lib/web/app/redirect.go @@ -51,8 +51,12 @@ const js = `