network.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. import * as errors from './errors.js';
  6. import * as platform from './platform.js';
  7. import { URI } from './uri.js';
  8. export var Schemas;
  9. (function (Schemas) {
  10. /**
  11. * A schema that is used for models that exist in memory
  12. * only and that have no correspondence on a server or such.
  13. */
  14. Schemas.inMemory = 'inmemory';
  15. /**
  16. * A schema that is used for setting files
  17. */
  18. Schemas.vscode = 'vscode';
  19. /**
  20. * A schema that is used for internal private files
  21. */
  22. Schemas.internal = 'private';
  23. /**
  24. * A walk-through document.
  25. */
  26. Schemas.walkThrough = 'walkThrough';
  27. /**
  28. * An embedded code snippet.
  29. */
  30. Schemas.walkThroughSnippet = 'walkThroughSnippet';
  31. Schemas.http = 'http';
  32. Schemas.https = 'https';
  33. Schemas.file = 'file';
  34. Schemas.mailto = 'mailto';
  35. Schemas.untitled = 'untitled';
  36. Schemas.data = 'data';
  37. Schemas.command = 'command';
  38. Schemas.vscodeRemote = 'vscode-remote';
  39. Schemas.vscodeRemoteResource = 'vscode-remote-resource';
  40. Schemas.vscodeUserData = 'vscode-userdata';
  41. Schemas.vscodeCustomEditor = 'vscode-custom-editor';
  42. Schemas.vscodeNotebookCell = 'vscode-notebook-cell';
  43. Schemas.vscodeNotebookCellMetadata = 'vscode-notebook-cell-metadata';
  44. Schemas.vscodeNotebookCellOutput = 'vscode-notebook-cell-output';
  45. Schemas.vscodeInteractive = 'vscode-interactive';
  46. Schemas.vscodeInteractiveInput = 'vscode-interactive-input';
  47. Schemas.vscodeSettings = 'vscode-settings';
  48. Schemas.vscodeWorkspaceTrust = 'vscode-workspace-trust';
  49. Schemas.vscodeTerminal = 'vscode-terminal';
  50. Schemas.vscodeInteractiveSesssion = 'vscode-chat-editor';
  51. /**
  52. * Scheme used internally for webviews that aren't linked to a resource (i.e. not custom editors)
  53. */
  54. Schemas.webviewPanel = 'webview-panel';
  55. /**
  56. * Scheme used for loading the wrapper html and script in webviews.
  57. */
  58. Schemas.vscodeWebview = 'vscode-webview';
  59. /**
  60. * Scheme used for extension pages
  61. */
  62. Schemas.extension = 'extension';
  63. /**
  64. * Scheme used as a replacement of `file` scheme to load
  65. * files with our custom protocol handler (desktop only).
  66. */
  67. Schemas.vscodeFileResource = 'vscode-file';
  68. /**
  69. * Scheme used for temporary resources
  70. */
  71. Schemas.tmp = 'tmp';
  72. /**
  73. * Scheme used vs live share
  74. */
  75. Schemas.vsls = 'vsls';
  76. /**
  77. * Scheme used for the Source Control commit input's text document
  78. */
  79. Schemas.vscodeSourceControl = 'vscode-scm';
  80. })(Schemas || (Schemas = {}));
  81. export const connectionTokenQueryName = 'tkn';
  82. class RemoteAuthoritiesImpl {
  83. constructor() {
  84. this._hosts = Object.create(null);
  85. this._ports = Object.create(null);
  86. this._connectionTokens = Object.create(null);
  87. this._preferredWebSchema = 'http';
  88. this._delegate = null;
  89. this._remoteResourcesPath = `/${Schemas.vscodeRemoteResource}`;
  90. }
  91. setPreferredWebSchema(schema) {
  92. this._preferredWebSchema = schema;
  93. }
  94. rewrite(uri) {
  95. if (this._delegate) {
  96. try {
  97. return this._delegate(uri);
  98. }
  99. catch (err) {
  100. errors.onUnexpectedError(err);
  101. return uri;
  102. }
  103. }
  104. const authority = uri.authority;
  105. let host = this._hosts[authority];
  106. if (host && host.indexOf(':') !== -1 && host.indexOf('[') === -1) {
  107. host = `[${host}]`;
  108. }
  109. const port = this._ports[authority];
  110. const connectionToken = this._connectionTokens[authority];
  111. let query = `path=${encodeURIComponent(uri.path)}`;
  112. if (typeof connectionToken === 'string') {
  113. query += `&${connectionTokenQueryName}=${encodeURIComponent(connectionToken)}`;
  114. }
  115. return URI.from({
  116. scheme: platform.isWeb ? this._preferredWebSchema : Schemas.vscodeRemoteResource,
  117. authority: `${host}:${port}`,
  118. path: this._remoteResourcesPath,
  119. query
  120. });
  121. }
  122. }
  123. export const RemoteAuthorities = new RemoteAuthoritiesImpl();
  124. class FileAccessImpl {
  125. /**
  126. * Returns a URI to use in contexts where the browser is responsible
  127. * for loading (e.g. fetch()) or when used within the DOM.
  128. *
  129. * **Note:** use `dom.ts#asCSSUrl` whenever the URL is to be used in CSS context.
  130. */
  131. uriToBrowserUri(uri) {
  132. // Handle remote URIs via `RemoteAuthorities`
  133. if (uri.scheme === Schemas.vscodeRemote) {
  134. return RemoteAuthorities.rewrite(uri);
  135. }
  136. // Convert to `vscode-file` resource..
  137. if (
  138. // ...only ever for `file` resources
  139. uri.scheme === Schemas.file &&
  140. (
  141. // ...and we run in native environments
  142. platform.isNative ||
  143. // ...or web worker extensions on desktop
  144. (platform.isWebWorker && platform.globals.origin === `${Schemas.vscodeFileResource}://${FileAccessImpl.FALLBACK_AUTHORITY}`))) {
  145. return uri.with({
  146. scheme: Schemas.vscodeFileResource,
  147. // We need to provide an authority here so that it can serve
  148. // as origin for network and loading matters in chromium.
  149. // If the URI is not coming with an authority already, we
  150. // add our own
  151. authority: uri.authority || FileAccessImpl.FALLBACK_AUTHORITY,
  152. query: null,
  153. fragment: null
  154. });
  155. }
  156. return uri;
  157. }
  158. }
  159. FileAccessImpl.FALLBACK_AUTHORITY = 'vscode-app';
  160. export const FileAccess = new FileAccessImpl();
  161. export var COI;
  162. (function (COI) {
  163. const coiHeaders = new Map([
  164. ['1', { 'Cross-Origin-Opener-Policy': 'same-origin' }],
  165. ['2', { 'Cross-Origin-Embedder-Policy': 'require-corp' }],
  166. ['3', { 'Cross-Origin-Opener-Policy': 'same-origin', 'Cross-Origin-Embedder-Policy': 'require-corp' }],
  167. ]);
  168. COI.CoopAndCoep = Object.freeze(coiHeaders.get('3'));
  169. const coiSearchParamName = 'vscode-coi';
  170. /**
  171. * Extract desired headers from `vscode-coi` invocation
  172. */
  173. function getHeadersFromQuery(url) {
  174. let params;
  175. if (typeof url === 'string') {
  176. params = new URL(url).searchParams;
  177. }
  178. else if (url instanceof URL) {
  179. params = url.searchParams;
  180. }
  181. else if (URI.isUri(url)) {
  182. params = new URL(url.toString(true)).searchParams;
  183. }
  184. const value = params === null || params === void 0 ? void 0 : params.get(coiSearchParamName);
  185. if (!value) {
  186. return undefined;
  187. }
  188. return coiHeaders.get(value);
  189. }
  190. COI.getHeadersFromQuery = getHeadersFromQuery;
  191. /**
  192. * Add the `vscode-coi` query attribute based on wanting `COOP` and `COEP`. Will be a noop when `crossOriginIsolated`
  193. * isn't enabled the current context
  194. */
  195. function addSearchParam(urlOrSearch, coop, coep) {
  196. if (!globalThis.crossOriginIsolated) {
  197. // depends on the current context being COI
  198. return;
  199. }
  200. const value = coop && coep ? '3' : coep ? '2' : '1';
  201. if (urlOrSearch instanceof URLSearchParams) {
  202. urlOrSearch.set(coiSearchParamName, value);
  203. }
  204. else {
  205. urlOrSearch[coiSearchParamName] = value;
  206. }
  207. }
  208. COI.addSearchParam = addSearchParam;
  209. })(COI || (COI = {}));