Skip to content

Commit aa2c51c

Browse files
jeanp413roboquat
authored andcommitted
Serve webview resources from blobserve
1 parent 3486caa commit aa2c51c

File tree

7 files changed

+38
-90
lines changed

7 files changed

+38
-90
lines changed

WORKSPACE.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ defaultArgs:
77
jbMarketplacePublishTrigger: "false"
88
publishToJBMarketplace: true
99
localAppVersion: unknown
10-
codeCommit: 9d98f338d0c8584b66195fceb555bb7223c755bc
10+
codeCommit: 32d5576921d1fb2a4891adb67f5003c554b04125
1111
codeQuality: stable
1212
jetbrainsBackendQualifier: stable
1313
intellijDownloadUrl: "https://download.jetbrains.com/idea/ideaIU-2022.1.1.tar.gz"

components/ide/code/leeway.Dockerfile

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,24 +46,20 @@ RUN yarn --frozen-lockfile --network-timeout 180000
4646
RUN rm -rf remote/node_modules/
4747
COPY --from=dependencies_builder /gp-code/remote/node_modules/ /gp-code/remote/node_modules/
4848

49+
# update product.json
4950
RUN nameShort=$(jq --raw-output '.nameShort' product.json) && \
5051
nameLong=$(jq --raw-output '.nameLong' product.json) && \
51-
echo $CODE_QUALITY && \
5252
if [ "$CODE_QUALITY" = "insider" ]; then \
5353
nameShort="$nameShort - Insiders" \
5454
nameLong="$nameLong - Insiders" \
5555
; fi && \
56-
setQuality='setpath(["quality"]; $codeQuality)' && \
57-
setNameShort='setpath(["nameShort"]; $nameShort)' && \
58-
setNameLong='setpath(["nameLong"]; $nameLong)' && \
56+
setQuality="setpath([\"quality\"]; \"$CODE_QUALITY\")" && \
57+
setNameShort="setpath([\"nameShort\"]; \"$nameShort\")" && \
58+
setNameLong="setpath([\"nameLong\"]; \"$nameLong\")" && \
5959
jqCommands="${setQuality} | ${setNameShort} | ${setNameLong}" && \
60-
cat product.json | jq \
61-
--arg codeQuality "$CODE_QUALITY" \
62-
--arg nameShort "$nameShort" \
63-
--arg nameLong "$nameLong" \
64-
"${jqCommands}" > product.json.tmp && \
60+
cat product.json | jq "${jqCommands}" > product.json.tmp && \
6561
mv product.json.tmp product.json && \
66-
cat product.json
62+
jq '{quality,nameLong,nameShort}' product.json
6763

6864
RUN yarn --cwd extensions compile \
6965
&& yarn gulp vscode-web-min \

components/proxy/conf/Caddyfile

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -326,19 +326,6 @@ https://*.*.{$GITPOD_DOMAIN} {
326326
}
327327
}
328328

329-
# REMOVE this once all workspaces have updated to new vscode version
330-
# old foreign content route used by vscode to serve webview and webworker resources
331-
# origin should be decoupled from the workspace (port) origin but the workspace (port) prefix should be the path root for routing
332-
@foreign_content header_regexp host Host ^.+-foreign.ws(-[a-z0-9]+)?.{$GITPOD_DOMAIN}
333-
handle @foreign_content {
334-
reverse_proxy https://ws-proxy.{$KUBE_NAMESPACE}.{$KUBE_DOMAIN}:9090 {
335-
import workspace_transport
336-
import upstream_headers
337-
338-
header_up X-WSProxy-Host {http.request.host}
339-
}
340-
}
341-
342329
# foreign content route used by vscode to serve webview and webworker resources of the form
343330
# https://{{hash_base_32}}.<cluster>.<gitpod_domain> or https://v--{{hash_base_32}}.<cluster>.<gitpod_domain>
344331
# e.g:

components/ws-proxy/pkg/proxy/routes.go

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -94,15 +94,6 @@ func installWorkspaceRoutes(r *mux.Router, config *RouteHandlerConfig, ip Worksp
9494
})
9595
routes.HandleSupervisorFrontendRoute(faviconRouter.NewRoute())
9696

97-
// Theia has a bunch of special routes it probably requires.
98-
// TODO(cw): figure out if these routes are still required, and how we deal with specialties of other IDEs.
99-
for _, pp := range []string{"/services", "/file-upload"} {
100-
routes.HandleDirectIDERoute(r.Path(pp))
101-
}
102-
for _, pp := range []string{"/mini-browser", "/file", "/files", "/hostedPlugin", "/webview"} {
103-
routes.HandleDirectIDERoute(r.PathPrefix(pp))
104-
}
105-
10697
routes.HandleSupervisorFrontendRoute(enableCompression(r).PathPrefix("/_supervisor/frontend"))
10798

10899
routes.HandleDirectSupervisorRoute(r.PathPrefix("/_supervisor/v1/status/supervisor"), false)

components/ws-proxy/pkg/proxy/routes_test.go

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -580,26 +580,6 @@ func TestRoutes(t *testing.T) {
580580
Body: "blobserve hit: /blobserve/gitpod-io/supervisor:latest/main.js\nreadOnly: true\n",
581581
},
582582
},
583-
{
584-
Desc: "extensions route GET",
585-
Request: modifyRequest(httptest.NewRequest("GET", "https://extensions-foreign.test-domain.com/"+workspaces[0].WorkspaceID+"/extensions.js", nil),
586-
addHostHeader,
587-
addHeader("Origin", config.GitpodInstallation.HostName),
588-
addOwnerToken(workspaces[0].InstanceID, workspaces[0].Auth.OwnerToken),
589-
),
590-
Expectation: Expectation{
591-
Status: http.StatusOK,
592-
Header: http.Header{
593-
"Access-Control-Allow-Credentials": {"true"},
594-
"Access-Control-Allow-Origin": {"test-domain.com"},
595-
"Access-Control-Expose-Headers": {"Authorization"},
596-
"Content-Length": {"30"},
597-
"Content-Type": {"text/plain; charset=utf-8"},
598-
"Vary": {"Accept-Encoding"},
599-
},
600-
Body: "workspace hit: /extensions.js\n",
601-
},
602-
},
603583
}
604584

605585
log.Init("ws-proxy-test", "", false, true)

components/ws-proxy/pkg/proxy/workspacerouter.go

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,10 @@ func matchWorkspaceHostHeader(wsHostSuffix string, headerProvider hostHeaderProv
8585
}
8686

8787
r := regexp.MustCompile("^" + regexPrefix + wsHostSuffix)
88-
foreignContentHostR := regexp.MustCompile("^(.+)(?:foreign)" + wsHostSuffix)
88+
89+
// REMOVE this once all workspaces have updated to new vscode version
8990
foreignContentHost2R := regexp.MustCompile("^((?:v--)?[0-9a-v]+)" + wsHostSuffix)
91+
9092
foreignContentPathR := regexp.MustCompile("^/" + regexPrefix + "(/.*)")
9193
return func(req *http.Request, m *mux.RouteMatch) bool {
9294
hostname := headerProvider(req)
@@ -95,21 +97,23 @@ func matchWorkspaceHostHeader(wsHostSuffix string, headerProvider hostHeaderProv
9597
}
9698

9799
var workspaceID, workspacePort, foreignOrigin, foreignPath string
98-
matches := foreignContentHostR.FindStringSubmatch(hostname)
99-
if len(matches) == 0 {
100-
matches = foreignContentHost2R.FindStringSubmatch(hostname)
101-
}
100+
matches := foreignContentHost2R.FindStringSubmatch(hostname)
102101
if len(matches) == 2 {
103102
foreignOrigin = matches[1]
103+
if strings.Contains(req.URL.Path, "/__files__/") {
104+
// REMOVE this once all workspaces have updated to new vscode version
105+
// Don't match if path contains `/__files__/` (blobserve image separator)
106+
return false
107+
}
104108
matches = foreignContentPathR.FindStringSubmatch(req.URL.Path)
105109
if matchPort {
106110
if len(matches) < 4 {
107111
return false
108112
}
109-
// https://extensions-foreign.ws-eu10.gitpod.io/3000-coral-dragon-ilr0r6eq/index.html
113+
// https://0d9rkrj560blqb5s07q431ru9mhg19k1k4bqgd1dbprtgmt7vuhk.ws-eu10.gitpod.io/3000-coral-dragon-ilr0r6eq/index.html
110114
// workspaceID: coral-dragon-ilr0r6eq
111115
// workspacePort: 3000
112-
// foreignOrigin: extensions-
116+
// foreignOrigin: 0d9rkrj560blqb5s07q431ru9mhg19k1k4bqgd1dbprtgmt7vuhk
113117
// foreignPath: /index.html
114118
workspaceID = matches[2]
115119
workspacePort = matches[1]
@@ -118,10 +122,10 @@ func matchWorkspaceHostHeader(wsHostSuffix string, headerProvider hostHeaderProv
118122
if len(matches) < 3 {
119123
return false
120124
}
121-
// https://extensions-foreign.ws-eu10.gitpod.io/coral-dragon-ilr0r6eq/index.html
125+
// https://0d9rkrj560blqb5s07q431ru9mhg19k1k4bqgd1dbprtgmt7vuhk.ws-eu10.gitpod.io/coral-dragon-ilr0r6eq/index.html
122126
// workspaceID: coral-dragon-ilr0r6eq
123127
// workspacePort:
124-
// foreignOrigin: extensions-
128+
// foreignOrigin: 0d9rkrj560blqb5s07q431ru9mhg19k1k4bqgd1dbprtgmt7vuhk
125129
// foreignPath: /index.html
126130
workspaceID = matches[1]
127131
foreignPath = matches[2]
@@ -180,14 +184,26 @@ func matchWorkspaceHostHeader(wsHostSuffix string, headerProvider hostHeaderProv
180184

181185
func matchBlobserveHostHeader(wsHostSuffix string, headerProvider hostHeaderProvider) mux.MatcherFunc {
182186
r := regexp.MustCompile("^blobserve" + wsHostSuffix)
187+
r2 := regexp.MustCompile("^(?:v--)?[0-9a-v]+" + wsHostSuffix)
183188
return func(req *http.Request, m *mux.RouteMatch) bool {
184189
hostname := headerProvider(req)
185190
if hostname == "" {
186191
return false
187192
}
188193

189194
matches := r.FindStringSubmatch(hostname)
190-
return len(matches) >= 1
195+
if len(matches) >= 1 {
196+
return true
197+
}
198+
199+
matches = r2.FindStringSubmatch(hostname)
200+
if len(matches) >= 1 && strings.Contains(req.URL.Path, "/__files__/") {
201+
// Check if path contains `/__files__/` for now as it could be using an
202+
// old vscode version serving webview resources from workspace
203+
return true
204+
}
205+
206+
return false
191207
}
192208
}
193209

components/ws-proxy/pkg/proxy/workspacerouter_test.go

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,11 @@ func TestMatchWorkspaceHostHeader(t *testing.T) {
156156
Name: "no host",
157157
HostHeader: "",
158158
},
159+
{
160+
Name: "no match 2",
161+
HostHeader: "0d9rkrj560blqb5s07q431ru9mhg19k1k4bqgd1dbprtgmt7vuhk" + wsHostSuffix,
162+
Path: "eu.gcr.io/gitpod-core-dev/build/ide/code:nightly@sha256:41aeea688aa0943bd746cb70c4ed378910f7c7ecf56f5f53ccb2b76c6b68e1a7/__files__/index.html",
163+
},
159164
{
160165
Name: "workspace match",
161166
HostHeader: "amaranth-smelt-9ba20cc1" + wsHostSuffix,
@@ -166,33 +171,6 @@ func TestMatchWorkspaceHostHeader(t *testing.T) {
166171
},
167172
},
168173
},
169-
{
170-
Name: "unique webview workspace match",
171-
HostHeader: "ad859a83-b5a8-43ef-8e82-cfbf36cafacb-webview-foreign" + wsHostSuffix,
172-
Path: "/amaranth-smelt-9ba20cc1/index.html",
173-
Expected: matchResult{
174-
MatchesWorkspace: true,
175-
WorkspaceVars: map[string]string{
176-
workspaceIDIdentifier: "amaranth-smelt-9ba20cc1",
177-
foreignOriginIdentifier: "ad859a83-b5a8-43ef-8e82-cfbf36cafacb-webview-",
178-
foreignPathIdentifier: "/index.html",
179-
},
180-
},
181-
},
182-
{
183-
Name: "unique webview port match",
184-
HostHeader: "ad859a83-b5a8-43ef-8e82-cfbf36cafacb-webview-foreign" + wsHostSuffix,
185-
Path: "/8080-amaranth-smelt-9ba20cc1/index.html",
186-
Expected: matchResult{
187-
MatchesPort: true,
188-
PortVars: map[string]string{
189-
workspaceIDIdentifier: "amaranth-smelt-9ba20cc1",
190-
workspacePortIdentifier: "8080",
191-
foreignOriginIdentifier: "ad859a83-b5a8-43ef-8e82-cfbf36cafacb-webview-",
192-
foreignPathIdentifier: "/index.html",
193-
},
194-
},
195-
},
196174
{
197175
Name: "unique webview workspace match 2",
198176
HostHeader: "0d9rkrj560blqb5s07q431ru9mhg19k1k4bqgd1dbprtgmt7vuhk" + wsHostSuffix,

0 commit comments

Comments
 (0)