Skip to content
This repository was archived by the owner on Jul 30, 2025. It is now read-only.

Commit 3551607

Browse files
committed
fix: fetchfile controller refuses any in-browser fetch, even if CORS would allow it
We should just try the network request, and let the browser fail it for us, rather than trying to be smart, here.
1 parent 0a6284a commit 3551607

File tree

3 files changed

+29
-18
lines changed

3 files changed

+29
-18
lines changed

plugins/plugin-client-common/notebook/src/load.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export async function loadNotebook(
2424
): Promise<string | object> {
2525
try {
2626
if (/^https:/.test(filepath)) {
27-
return (await REPL.rexec<(string | object)[]>(`_fetchfile ${encodeComponent(filepath)}`)).content[0]
27+
return (await REPL.rexec<(string | object)[]>(`vfs _fetchfile ${encodeComponent(filepath)}`)).content[0]
2828
} else {
2929
// --with-data says give us the file contents
3030
const fullpath = Util.absolute(Util.expandHomeDir(filepath))

plugins/plugin-kubectl/src/controller/fetch-file.ts

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,22 @@ async function fetchKustomizeString(
6868
}
6969
}
7070

71+
async function fetchFileController(args: Arguments<Options>) {
72+
const { argvNoOptions, parsedOptions, execOptions } = args
73+
74+
const uri = argvNoOptions[argvNoOptions.indexOf('_fetchfile') + 1]
75+
const opts = Object.assign(
76+
{ tryFetchEvenInBrowser: true },
77+
typeof execOptions.data === 'object' && !Buffer.isBuffer(execOptions.data) ? execOptions.data : undefined
78+
)
79+
80+
if (!parsedOptions.kustomize) {
81+
return { mode: 'raw', content: await fetchFile(args, uri, opts) }
82+
} else {
83+
return { mode: 'raw', content: await fetchKustomizeString(args, uri) }
84+
}
85+
}
86+
7187
/**
7288
* A server-side shim to allow browser-based clients to fetch `-f`
7389
* file content.
@@ -115,21 +131,15 @@ export default (registrar: Registrar) => {
115131
{ requiresLocal: true }
116132
)
117133

118-
registrar.listen(
119-
`/_fetchfile`,
120-
async (args: Arguments<Options>) => {
121-
const { argvNoOptions, parsedOptions, execOptions } = args
122-
123-
const uri = argvNoOptions[argvNoOptions.indexOf('_fetchfile') + 1]
124-
const opts =
125-
typeof execOptions.data === 'object' && !Buffer.isBuffer(execOptions.data) ? execOptions.data : undefined
134+
/**
135+
* WARNING: called **internally** by util/fetch-file.ts to
136+
* facilitate the browser-to-proxy hand-off.
137+
*/
138+
registrar.listen(`/_fetchfile`, fetchFileController, { requiresLocal: true, flags: { boolean: ['kustomize'] } })
126139

127-
if (!parsedOptions.kustomize) {
128-
return { mode: 'raw', content: await fetchFile(args, uri, opts) }
129-
} else {
130-
return { mode: 'raw', content: await fetchKustomizeString(args, uri) }
131-
}
132-
},
133-
{ requiresLocal: true, flags: { boolean: ['kustomize'] } }
134-
)
140+
/**
141+
* Called by anyone; note the requiresLocal difference here. This is
142+
* to allow fetches from a browser when CORS supports it.
143+
*/
144+
registrar.listen(`/vfs/_fetchfile`, fetchFileController, { flags: { boolean: ['kustomize'] } })
135145
}

plugins/plugin-kubectl/src/lib/util/fetch-file.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ interface FetchOptions<Data extends BodyData | BodyData[]> {
129129
data?: Data
130130
headers?: Record<string, string>
131131
method?: 'get' | 'put' | 'post' | 'delete'
132+
tryFetchEvenInBrowser?: boolean
132133
}
133134

134135
export async function _needle(
@@ -137,7 +138,7 @@ export async function _needle(
137138
opts?: FetchOptions<BodyData>,
138139
retryCount = 0
139140
): Promise<{ statusCode: number; body: string | object }> {
140-
if (!Capabilities.inBrowser()) {
141+
if (!Capabilities.inBrowser() || (opts && opts.tryFetchEvenInBrowser)) {
141142
const method = (opts && opts.method) || 'get'
142143
const headers = Object.assign({ connection: 'keep-alive' }, opts.headers)
143144
debug('fetch via needle', method, headers, url)

0 commit comments

Comments
 (0)