@@ -21,8 +21,11 @@ const (
21
21
// Used as key for storing the workspace ID in the requests mux.Vars() map
22
22
workspaceIDIdentifier = "workspaceID"
23
23
24
- // Used as key for storing the origin prefix to fetch foreign content
25
- foreignOriginPrefix = "foreignOriginPrefix"
24
+ // Used as key for storing the origin to fetch foreign content
25
+ foreignOriginIdentifier = "foreignOrigin"
26
+
27
+ // Used as key for storing the path to fetch foreign content
28
+ foreignPathIdentifier = "foreignPath"
26
29
27
30
// The header that is used to communicate the "Host" from proxy -> ws-proxy in scenarios where ws-proxy is _not_ directly exposed
28
31
forwardedHostnameHeader = "x-wsproxy-host"
@@ -56,8 +59,8 @@ func HostBasedRouter(header, wsHostSuffix string, wsHostSuffixRegex string) Work
56
59
return req .Header .Get (header )
57
60
}
58
61
blobserveRouter = r .MatcherFunc (matchBlobserveHostHeader (wsHostSuffix , getHostHeader )).Subrouter ()
59
- portRouter = r .MatcherFunc (matchWorkspacePortHostHeader (wsHostSuffix , getHostHeader )).Subrouter ()
60
- ideRouter = r .MatcherFunc (matchWorkspaceHostHeader (allClusterWsHostSuffixRegex , getHostHeader )).Subrouter ()
62
+ portRouter = r .MatcherFunc (matchWorkspaceHostHeader (wsHostSuffix , getHostHeader , true )).Subrouter ()
63
+ ideRouter = r .MatcherFunc (matchWorkspaceHostHeader (allClusterWsHostSuffixRegex , getHostHeader , false )).Subrouter ()
61
64
)
62
65
63
66
r .NotFoundHandler = http .HandlerFunc (func (w http.ResponseWriter , req * http.Request ) {
@@ -71,65 +74,113 @@ func HostBasedRouter(header, wsHostSuffix string, wsHostSuffixRegex string) Work
71
74
72
75
type hostHeaderProvider func (req * http.Request ) string
73
76
74
- func matchWorkspaceHostHeader (wsHostSuffix string , headerProvider hostHeaderProvider ) mux.MatcherFunc {
75
- r := regexp .MustCompile ("^(webview-|browser-|extensions-)?" + workspaceIDRegex + wsHostSuffix )
76
- return func (req * http.Request , m * mux.RouteMatch ) bool {
77
- hostname := headerProvider (req )
78
- if hostname == "" {
79
- return false
80
- }
81
-
82
- matches := r .FindStringSubmatch (hostname )
83
- if len (matches ) < 3 {
84
- return false
85
- }
86
-
87
- workspaceID := matches [2 ]
88
- if workspaceID == "" {
89
- return false
90
- }
91
-
92
- if m .Vars == nil {
93
- m .Vars = make (map [string ]string )
94
- }
95
- m .Vars [workspaceIDIdentifier ] = workspaceID
96
- if len (matches ) == 3 {
97
- m .Vars [foreignOriginPrefix ] = matches [1 ]
98
- }
99
- return true
77
+ func matchWorkspaceHostHeader (wsHostSuffix string , headerProvider hostHeaderProvider , matchPort bool ) mux.MatcherFunc {
78
+ regexPrefix := workspaceIDRegex
79
+ if matchPort {
80
+ regexPrefix = workspacePortRegex + workspaceIDRegex
100
81
}
101
- }
102
82
103
- func matchWorkspacePortHostHeader (wsHostSuffix string , headerProvider hostHeaderProvider ) mux.MatcherFunc {
104
- r := regexp .MustCompile ("^(webview-|browser-|extensions-)?" + workspacePortRegex + workspaceIDRegex + wsHostSuffix )
83
+ // remove (webview-|browser-|extensions-) prefix as soon as Theia removed and new VS Code is used in all workspaces
84
+ r := regexp .MustCompile ("^(webview-|browser-|extensions-)?" + regexPrefix + wsHostSuffix )
85
+ foreignContentHostR := regexp .MustCompile ("^(.+)(?:foreign)" + wsHostSuffix )
86
+ foreignContentPathR := regexp .MustCompile ("^/" + regexPrefix + "(/.*)" )
105
87
return func (req * http.Request , m * mux.RouteMatch ) bool {
106
88
hostname := headerProvider (req )
107
89
if hostname == "" {
108
90
return false
109
91
}
110
92
111
- matches := r .FindStringSubmatch (hostname )
112
- if len (matches ) < 4 {
113
- return false
93
+ var workspaceID , workspacePort , foreignOrigin , foreignPath string
94
+ matches := foreignContentHostR .FindStringSubmatch (hostname )
95
+ if len (matches ) == 2 {
96
+ foreignOrigin = matches [1 ]
97
+ matches = foreignContentPathR .FindStringSubmatch (req .URL .Path )
98
+ if matchPort {
99
+ if len (matches ) < 4 {
100
+ return false
101
+ }
102
+ // https://extensions-foreign.ws-eu10.gitpod.io/3000-coral-dragon-ilr0r6eq/index.html
103
+ // workspaceID: coral-dragon-ilr0r6eq
104
+ // workspacePort: 3000
105
+ // foreignOrigin: extensions-
106
+ // foreignPath: /index.html
107
+ workspaceID = matches [2 ]
108
+ workspacePort = matches [1 ]
109
+ foreignPath = matches [3 ]
110
+ } else {
111
+ if len (matches ) < 3 {
112
+ return false
113
+ }
114
+ // https://extensions-foreign.ws-eu10.gitpod.io/coral-dragon-ilr0r6eq/index.html
115
+ // workspaceID: coral-dragon-ilr0r6eq
116
+ // workspacePort:
117
+ // foreignOrigin: extensions-
118
+ // foreignPath: /index.html
119
+ workspaceID = matches [1 ]
120
+ foreignPath = matches [2 ]
121
+ }
122
+ } else {
123
+ matches = r .FindStringSubmatch (hostname )
124
+ if matchPort {
125
+ if len (matches ) < 4 {
126
+ return false
127
+ }
128
+ // https://3000-coral-dragon-ilr0r6eq.ws-eu10.gitpod.io/index.html
129
+ // workspaceID: coral-dragon-ilr0r6eq
130
+ // workspacePort: 3000
131
+ // foreignOrigin:
132
+ // foreignPath:
133
+ workspaceID = matches [3 ]
134
+ workspacePort = matches [2 ]
135
+ if len (matches ) == 4 {
136
+ // https://extensions-3000-coral-dragon-ilr0r6eq.ws-eu10.gitpod.io/index.html
137
+ // workspaceID: coral-dragon-ilr0r6eq
138
+ // workspacePort: 3000
139
+ // foreignOrigin: extensions-
140
+ // foreignPath:
141
+ foreignOrigin = matches [1 ]
142
+ }
143
+ } else {
144
+ if len (matches ) < 3 {
145
+ return false
146
+ }
147
+ // https://coral-dragon-ilr0r6eq.ws-eu10.gitpod.io/index.html
148
+ // workspaceID: coral-dragon-ilr0r6eq
149
+ // workspacePort:
150
+ // foreignOrigin:
151
+ // foreignPath:
152
+ workspaceID = matches [2 ]
153
+ if len (matches ) == 3 {
154
+ // https://extensions-coral-dragon-ilr0r6eq.ws-eu10.gitpod.io/index.html
155
+ // workspaceID: coral-dragon-ilr0r6eq
156
+ // workspacePort:
157
+ // foreignOrigin: extensions-
158
+ // foreignPath:
159
+ foreignOrigin = matches [1 ]
160
+ }
161
+ }
114
162
}
115
163
116
- workspaceID := matches [3 ]
117
164
if workspaceID == "" {
118
165
return false
119
166
}
120
167
121
- workspacePort := matches [2 ]
122
- if workspacePort == "" {
168
+ if matchPort && workspacePort == "" {
123
169
return false
124
170
}
125
171
126
172
if m .Vars == nil {
127
173
m .Vars = make (map [string ]string )
128
174
}
129
175
m .Vars [workspaceIDIdentifier ] = workspaceID
130
- m .Vars [workspacePortIdentifier ] = workspacePort
131
- if len (matches ) == 4 {
132
- m .Vars [foreignOriginPrefix ] = matches [1 ]
176
+ if workspacePort != "" {
177
+ m .Vars [workspacePortIdentifier ] = workspacePort
178
+ }
179
+ if foreignOrigin != "" {
180
+ m .Vars [foreignOriginIdentifier ] = foreignOrigin
181
+ }
182
+ if foreignPath != "" {
183
+ m .Vars [foreignPathIdentifier ] = foreignPath
133
184
}
134
185
return true
135
186
}
0 commit comments