Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/extensions/copilot/src/util/vs/base/common/network.ts
13405 views
1
//!!! DO NOT modify, this file was COPIED from 'microsoft/vscode'
2
3
/*---------------------------------------------------------------------------------------------
4
* Copyright (c) Microsoft Corporation. All rights reserved.
5
* Licensed under the MIT License. See License.txt in the project root for license information.
6
*--------------------------------------------------------------------------------------------*/
7
8
import * as errors from './errors';
9
import * as platform from './platform';
10
import { equalsIgnoreCase, startsWithIgnoreCase } from './strings';
11
import { URI } from './uri';
12
import * as paths from './path';
13
14
export namespace Schemas {
15
16
/**
17
* A schema that is used for models that exist in memory
18
* only and that have no correspondence on a server or such.
19
*/
20
export const inMemory = 'inmemory';
21
22
/**
23
* A schema that is used for setting files
24
*/
25
export const vscode = 'vscode';
26
27
/**
28
* A schema that is used for internal private files
29
*/
30
export const internal = 'private';
31
32
/**
33
* A walk-through document.
34
*/
35
export const walkThrough = 'walkThrough';
36
37
/**
38
* An embedded code snippet.
39
*/
40
export const walkThroughSnippet = 'walkThroughSnippet';
41
42
export const http = 'http';
43
44
export const https = 'https';
45
46
export const file = 'file';
47
48
export const mailto = 'mailto';
49
50
export const untitled = 'untitled';
51
52
export const data = 'data';
53
54
export const command = 'command';
55
56
export const vscodeRemote = 'vscode-remote';
57
58
export const vscodeRemoteResource = 'vscode-remote-resource';
59
60
export const vscodeManagedRemoteResource = 'vscode-managed-remote-resource';
61
62
export const vscodeUserData = 'vscode-userdata';
63
64
export const vscodeCustomEditor = 'vscode-custom-editor';
65
66
export const vscodeNotebookCell = 'vscode-notebook-cell';
67
export const vscodeNotebookCellMetadata = 'vscode-notebook-cell-metadata';
68
export const vscodeNotebookCellMetadataDiff = 'vscode-notebook-cell-metadata-diff';
69
export const vscodeNotebookCellOutput = 'vscode-notebook-cell-output';
70
export const vscodeNotebookCellOutputDiff = 'vscode-notebook-cell-output-diff';
71
export const vscodeNotebookMetadata = 'vscode-notebook-metadata';
72
export const vscodeInteractiveInput = 'vscode-interactive-input';
73
74
export const vscodeSettings = 'vscode-settings';
75
76
export const vscodeWorkspaceTrust = 'vscode-workspace-trust';
77
78
export const vscodeTerminal = 'vscode-terminal';
79
80
/** Scheme used for code blocks in chat. */
81
export const vscodeChatCodeBlock = 'vscode-chat-code-block';
82
83
/** Scheme used for LHS of code compare (aka diff) blocks in chat. */
84
export const vscodeChatCodeCompareBlock = 'vscode-chat-code-compare-block';
85
86
/** Scheme used for the chat input editor. */
87
export const vscodeChatEditor = 'vscode-chat-editor';
88
89
/** Scheme used for the chat input part */
90
export const vscodeChatInput = 'chatSessionInput';
91
92
/** Scheme used for local chat session content */
93
export const vscodeLocalChatSession = 'vscode-chat-session';
94
95
/**
96
* Scheme used internally for webviews that aren't linked to a resource (i.e. not custom editors)
97
*/
98
export const webviewPanel = 'webview-panel';
99
100
/**
101
* Scheme used for loading the wrapper html and script in webviews.
102
*/
103
export const vscodeWebview = 'vscode-webview';
104
105
/**
106
* Scheme used for integrated browser tabs using WebContentsView.
107
*/
108
export const vscodeBrowser = 'vscode-browser';
109
110
/**
111
* Scheme used for extension pages
112
*/
113
export const extension = 'extension';
114
115
/**
116
* Scheme used as a replacement of `file` scheme to load
117
* files with our custom protocol handler (desktop only).
118
*/
119
export const vscodeFileResource = 'vscode-file';
120
121
/**
122
* Scheme used for temporary resources
123
*/
124
export const tmp = 'tmp';
125
126
/**
127
* Scheme used vs live share
128
*/
129
export const vsls = 'vsls';
130
131
/**
132
* Scheme used for the Source Control commit input's text document
133
*/
134
export const vscodeSourceControl = 'vscode-scm';
135
136
/**
137
* Scheme used for input box for creating comments.
138
*/
139
export const commentsInput = 'comment';
140
141
/**
142
* Scheme used for special rendering of settings in the release notes
143
*/
144
export const codeSetting = 'code-setting';
145
146
/**
147
* Scheme used for output panel resources
148
*/
149
export const outputChannel = 'output';
150
151
/**
152
* Scheme used for the accessible view
153
*/
154
export const accessibleView = 'accessible-view';
155
156
/**
157
* Used for snapshots of chat edits
158
*/
159
export const chatEditingSnapshotScheme = 'chat-editing-snapshot-text-model';
160
export const chatEditingModel = 'chat-editing-text-model';
161
162
/**
163
* Used for rendering multidiffs in copilot agent sessions
164
*/
165
export const copilotPr = 'copilot-pr';
166
}
167
168
export function matchesScheme(target: URI | string, scheme: string): boolean {
169
if (URI.isUri(target)) {
170
return equalsIgnoreCase(target.scheme, scheme);
171
} else {
172
return startsWithIgnoreCase(target, scheme + ':');
173
}
174
}
175
176
export function matchesSomeScheme(target: URI | string, ...schemes: string[]): boolean {
177
return schemes.some(scheme => matchesScheme(target, scheme));
178
}
179
180
export const connectionTokenCookieName = 'vscode-tkn';
181
export const connectionTokenQueryName = 'tkn';
182
183
class RemoteAuthoritiesImpl {
184
private readonly _hosts: { [authority: string]: string | undefined } = Object.create(null);
185
private readonly _ports: { [authority: string]: number | undefined } = Object.create(null);
186
private readonly _connectionTokens: { [authority: string]: string | undefined } = Object.create(null);
187
private _preferredWebSchema: 'http' | 'https' = 'http';
188
private _delegate: ((uri: URI) => URI) | null = null;
189
private _serverRootPath: string = '/';
190
191
setPreferredWebSchema(schema: 'http' | 'https') {
192
this._preferredWebSchema = schema;
193
}
194
195
setDelegate(delegate: (uri: URI) => URI): void {
196
this._delegate = delegate;
197
}
198
199
setServerRootPath(product: { quality?: string; commit?: string }, serverBasePath: string | undefined): void {
200
this._serverRootPath = paths.posix.join(serverBasePath ?? '/', getServerProductSegment(product));
201
}
202
203
getServerRootPath(): string {
204
return this._serverRootPath;
205
}
206
207
private get _remoteResourcesPath(): string {
208
return paths.posix.join(this._serverRootPath, Schemas.vscodeRemoteResource);
209
}
210
211
set(authority: string, host: string, port: number): void {
212
this._hosts[authority] = host;
213
this._ports[authority] = port;
214
}
215
216
setConnectionToken(authority: string, connectionToken: string): void {
217
this._connectionTokens[authority] = connectionToken;
218
}
219
220
getPreferredWebSchema(): 'http' | 'https' {
221
return this._preferredWebSchema;
222
}
223
224
rewrite(uri: URI): URI {
225
if (this._delegate) {
226
try {
227
return this._delegate(uri);
228
} catch (err) {
229
errors.onUnexpectedError(err);
230
return uri;
231
}
232
}
233
const authority = uri.authority;
234
let host = this._hosts[authority];
235
if (host && host.indexOf(':') !== -1 && host.indexOf('[') === -1) {
236
host = `[${host}]`;
237
}
238
const port = this._ports[authority];
239
const connectionToken = this._connectionTokens[authority];
240
let query = `path=${encodeURIComponent(uri.path)}`;
241
if (typeof connectionToken === 'string') {
242
query += `&${connectionTokenQueryName}=${encodeURIComponent(connectionToken)}`;
243
}
244
return URI.from({
245
scheme: platform.isWeb ? this._preferredWebSchema : Schemas.vscodeRemoteResource,
246
authority: `${host}:${port}`,
247
path: this._remoteResourcesPath,
248
query
249
});
250
}
251
}
252
253
export const RemoteAuthorities = new RemoteAuthoritiesImpl();
254
255
export function getServerProductSegment(product: { quality?: string; commit?: string }) {
256
return `${product.quality ?? 'oss'}-${product.commit ?? 'dev'}`;
257
}
258
259
/**
260
* A string pointing to a path inside the app. It should not begin with ./ or ../
261
*/
262
export type AppResourcePath = (
263
`a${string}` | `b${string}` | `c${string}` | `d${string}` | `e${string}` | `f${string}`
264
| `g${string}` | `h${string}` | `i${string}` | `j${string}` | `k${string}` | `l${string}`
265
| `m${string}` | `n${string}` | `o${string}` | `p${string}` | `q${string}` | `r${string}`
266
| `s${string}` | `t${string}` | `u${string}` | `v${string}` | `w${string}` | `x${string}`
267
| `y${string}` | `z${string}`
268
);
269
270
export const builtinExtensionsPath: AppResourcePath = 'vs/../../extensions';
271
export const nodeModulesPath: AppResourcePath = 'vs/../../node_modules';
272
export const nodeModulesAsarPath: AppResourcePath = 'vs/../../node_modules.asar';
273
export const nodeModulesAsarUnpackedPath: AppResourcePath = 'vs/../../node_modules.asar.unpacked';
274
275
export const VSCODE_AUTHORITY = 'vscode-app';
276
277
class FileAccessImpl {
278
279
private static readonly FALLBACK_AUTHORITY = VSCODE_AUTHORITY;
280
281
/**
282
* Returns a URI to use in contexts where the browser is responsible
283
* for loading (e.g. fetch()) or when used within the DOM.
284
*
285
* **Note:** use `dom.ts#asCSSUrl` whenever the URL is to be used in CSS context.
286
*/
287
asBrowserUri(resourcePath: AppResourcePath | ''): URI {
288
const uri = this.toUri(resourcePath);
289
return this.uriToBrowserUri(uri);
290
}
291
292
/**
293
* Returns a URI to use in contexts where the browser is responsible
294
* for loading (e.g. fetch()) or when used within the DOM.
295
*
296
* **Note:** use `dom.ts#asCSSUrl` whenever the URL is to be used in CSS context.
297
*/
298
uriToBrowserUri(uri: URI): URI {
299
// Handle remote URIs via `RemoteAuthorities`
300
if (uri.scheme === Schemas.vscodeRemote) {
301
return RemoteAuthorities.rewrite(uri);
302
}
303
304
// Convert to `vscode-file` resource..
305
if (
306
// ...only ever for `file` resources
307
uri.scheme === Schemas.file &&
308
(
309
// ...and we run in native environments
310
platform.isNative ||
311
// ...or web worker extensions on desktop
312
(platform.webWorkerOrigin === `${Schemas.vscodeFileResource}://${FileAccessImpl.FALLBACK_AUTHORITY}`)
313
)
314
) {
315
return uri.with({
316
scheme: Schemas.vscodeFileResource,
317
// We need to provide an authority here so that it can serve
318
// as origin for network and loading matters in chromium.
319
// If the URI is not coming with an authority already, we
320
// add our own
321
authority: uri.authority || FileAccessImpl.FALLBACK_AUTHORITY,
322
query: null,
323
fragment: null
324
});
325
}
326
327
return uri;
328
}
329
330
/**
331
* Returns the `file` URI to use in contexts where node.js
332
* is responsible for loading.
333
*/
334
asFileUri(resourcePath: AppResourcePath | ''): URI {
335
const uri = this.toUri(resourcePath);
336
return this.uriToFileUri(uri);
337
}
338
339
/**
340
* Returns the `file` URI to use in contexts where node.js
341
* is responsible for loading.
342
*/
343
uriToFileUri(uri: URI): URI {
344
// Only convert the URI if it is `vscode-file:` scheme
345
if (uri.scheme === Schemas.vscodeFileResource) {
346
return uri.with({
347
scheme: Schemas.file,
348
// Only preserve the `authority` if it is different from
349
// our fallback authority. This ensures we properly preserve
350
// Windows UNC paths that come with their own authority.
351
authority: uri.authority !== FileAccessImpl.FALLBACK_AUTHORITY ? uri.authority : null,
352
query: null,
353
fragment: null
354
});
355
}
356
357
return uri;
358
}
359
360
private toUri(uriOrModule: URI | string): URI {
361
if (URI.isUri(uriOrModule)) {
362
return uriOrModule;
363
}
364
365
if (globalThis._VSCODE_FILE_ROOT) {
366
const rootUriOrPath = globalThis._VSCODE_FILE_ROOT;
367
368
// File URL (with scheme)
369
if (/^\w[\w\d+.-]*:\/\//.test(rootUriOrPath)) {
370
return URI.joinPath(URI.parse(rootUriOrPath, true), uriOrModule);
371
}
372
373
// File Path (no scheme)
374
const modulePath = paths.join(rootUriOrPath, uriOrModule);
375
return URI.file(modulePath);
376
}
377
378
throw new Error('Cannot determine URI for module id!');
379
}
380
}
381
382
export const FileAccess = new FileAccessImpl();
383
384
export const CacheControlheaders: Record<string, string> = Object.freeze({
385
'Cache-Control': 'no-cache, no-store'
386
});
387
388
export const DocumentPolicyheaders: Record<string, string> = Object.freeze({
389
'Document-Policy': 'include-js-call-stacks-in-crash-reports'
390
});
391
392
export namespace COI {
393
394
const coiHeaders = new Map<'3' | '2' | '1' | string, Record<string, string>>([
395
['1', { 'Cross-Origin-Opener-Policy': 'same-origin' }],
396
['2', { 'Cross-Origin-Embedder-Policy': 'require-corp' }],
397
['3', { 'Cross-Origin-Opener-Policy': 'same-origin', 'Cross-Origin-Embedder-Policy': 'require-corp' }],
398
]);
399
400
export const CoopAndCoep = Object.freeze(coiHeaders.get('3'));
401
402
const coiSearchParamName = 'vscode-coi';
403
404
/**
405
* Extract desired headers from `vscode-coi` invocation
406
*/
407
export function getHeadersFromQuery(url: string | URI | URL): Record<string, string> | undefined {
408
let params: URLSearchParams | undefined;
409
if (typeof url === 'string') {
410
params = new URL(url).searchParams;
411
} else if (url instanceof URL) {
412
params = url.searchParams;
413
} else if (URI.isUri(url)) {
414
params = new URL(url.toString(true)).searchParams;
415
}
416
const value = params?.get(coiSearchParamName);
417
if (!value) {
418
return undefined;
419
}
420
return coiHeaders.get(value);
421
}
422
423
/**
424
* Add the `vscode-coi` query attribute based on wanting `COOP` and `COEP`. Will be a noop when `crossOriginIsolated`
425
* isn't enabled the current context
426
*/
427
export function addSearchParam(urlOrSearch: URLSearchParams | Record<string, string>, coop: boolean, coep: boolean): void {
428
if (!(globalThis as typeof globalThis & { crossOriginIsolated?: boolean }).crossOriginIsolated) {
429
// depends on the current context being COI
430
return;
431
}
432
const value = coop && coep ? '3' : coep ? '2' : '1';
433
if (urlOrSearch instanceof URLSearchParams) {
434
urlOrSearch.set(coiSearchParamName, value);
435
} else {
436
urlOrSearch[coiSearchParamName] = value;
437
}
438
}
439
}
440
441