Skip to content

Commit 51f9c9c

Browse files
authored
Merge pull request #359 from redhat-developer/content-request
Register a non-standard LSP content request for resolving schemas on the client side
2 parents ce1609d + c07059b commit 51f9c9c

4 files changed

Lines changed: 52 additions & 8 deletions

File tree

src/languageservice/services/schemaRequestHandler.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,30 @@
11
import { URI } from 'vscode-uri';
2-
import { IConnection } from 'vscode-languageserver';
2+
import { IConnection, WorkspaceFolder } from 'vscode-languageserver';
33
import { xhr, XHRResponse, getErrorStatusDescription } from 'request-light';
44
import * as fs from 'fs';
55

6-
import { CustomSchemaContentRequest } from '../../requestTypes';
6+
import { CustomSchemaContentRequest, VSCodeContentRequest } from '../../requestTypes';
77
import { isRelativePath, relativeToAbsolutePath } from '../utils/paths';
88

99
/**
1010
* Handles schema content requests given the schema URI
1111
* @param uri can be a local file, vscode request, http(s) request or a custom request
1212
*/
13-
export const schemaRequestHandler = (connection: IConnection, uri: string): Promise<string> => {
13+
export const schemaRequestHandler = (
14+
connection: IConnection,
15+
uri: string,
16+
workspaceFolders: WorkspaceFolder[],
17+
workspaceRoot: URI,
18+
useVSCodeContentRequest: boolean
19+
): Promise<string> => {
1420
if (!uri) {
1521
return Promise.reject('No schema specified');
1622
}
1723

1824
// If the requested schema URI is a relative file path
1925
// Convert it into a proper absolute path URI
2026
if (isRelativePath(uri)) {
21-
uri = relativeToAbsolutePath(this.workspaceFolders, this.workspaceRoot, uri);
27+
uri = relativeToAbsolutePath(workspaceFolders, workspaceRoot, uri);
2228
}
2329

2430
let scheme = URI.parse(uri).scheme.toLowerCase();
@@ -47,6 +53,19 @@ export const schemaRequestHandler = (connection: IConnection, uri: string): Prom
4753

4854
// HTTP(S) requests are sent and the response result is either the schema content or an error
4955
if (scheme === 'http' || scheme === 'https') {
56+
// If we are running inside of VSCode we need to make a content request. This content request
57+
// will make it so that schemas behind VPN's will resolve correctly
58+
if (useVSCodeContentRequest) {
59+
return connection.sendRequest(VSCodeContentRequest.type, uri).then(
60+
(responseText) => {
61+
return responseText;
62+
},
63+
(error) => {
64+
return Promise.reject(error.message);
65+
}
66+
) as Promise<string>;
67+
}
68+
5069
// Send the HTTP(S) schema content request and return the result
5170
const headers = { 'Accept-Encoding': 'gzip, deflate' };
5271
return xhr({ url: uri, followRedirects: 5, headers }).then(

src/requestTypes.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ export namespace DynamicCustomSchemaRequestRegistration {
1717
export const type: NotificationType<{}, {}> = new NotificationType('yaml/registerCustomSchemaRequest');
1818
}
1919

20+
export namespace VSCodeContentRequestRegistration {
21+
export const type: NotificationType<{}, {}> = new NotificationType('yaml/registerContentRequest');
22+
}
23+
2024
export namespace VSCodeContentRequest {
2125
export const type: RequestType<{}, {}, {}, {}> = new RequestType('vscode/content');
2226
}

src/server.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,13 @@ import {
4646
CustomSchemaRequest,
4747
SchemaModificationNotification,
4848
ISchemaAssociations,
49+
VSCodeContentRequestRegistration,
4950
} from './requestTypes';
50-
import { schemaRequestHandler } from './languageservice/services/schemaRequestHandler';
5151
import { isRelativePath, relativeToAbsolutePath, workspaceFoldersChanged } from './languageservice/utils/paths';
5252
import { URI } from 'vscode-uri';
5353
import { KUBERNETES_SCHEMA_URL, JSON_SCHEMASTORE_URL } from './languageservice/utils/schemaUrls';
54+
import { schemaRequestHandler } from './languageservice/services/schemaRequestHandler';
55+
5456
// eslint-disable-next-line @typescript-eslint/no-explicit-any
5557
nls.config(process.env['VSCODE_NLS_CONFIG'] as any);
5658

@@ -136,6 +138,7 @@ let workspaceFolders: WorkspaceFolder[] = [];
136138
let clientDynamicRegisterSupport = false;
137139
let hierarchicalDocumentSymbolSupport = false;
138140
let hasWorkspaceFolderCapability = false;
141+
let useVSCodeContentRequest = false;
139142

140143
/****************************
141144
* Reusable helper functions
@@ -373,7 +376,15 @@ console.error = connection.console.error.bind(connection.console);
373376
// for open, change and close text document events
374377
documents.listen(connection);
375378

376-
const schemaRequestService = schemaRequestHandler.bind(this, connection);
379+
/**
380+
* Handles schema content requests given the schema URI
381+
* @param uri can be a local file, vscode request, http(s) request or a custom request
382+
*/
383+
const schemaRequestHandlerWrapper = (connection: IConnection, uri: string): Promise<string> => {
384+
return schemaRequestHandler(connection, uri, workspaceFolders, workspaceRoot, useVSCodeContentRequest);
385+
};
386+
387+
const schemaRequestService = schemaRequestHandlerWrapper.bind(this, connection);
377388

378389
export const customLanguageService = getCustomLanguageService(schemaRequestService, workspaceContext);
379390

@@ -456,6 +467,15 @@ connection.onNotification(DynamicCustomSchemaRequestRegistration.type, () => {
456467
customLanguageService.registerCustomSchemaProvider(schemaProvider);
457468
});
458469

470+
/**
471+
* Received a notification from the client that it can accept content requests
472+
* This means that the server sends schemas back to the client side to get resolved rather
473+
* than resolving them on the extension side
474+
*/
475+
connection.onNotification(VSCodeContentRequestRegistration.type, () => {
476+
useVSCodeContentRequest = true;
477+
});
478+
459479
/**
460480
* Run when the editor configuration is changed
461481
* The client syncs the 'yaml', 'http.proxy', 'http.proxyStrictSSL' settings sections
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import * as sinon from 'sinon';
88
import * as fs from 'fs';
99
import { IConnection } from 'vscode-languageserver';
1010
import * as assert from 'assert';
11+
import { URI } from 'vscode-uri';
1112

1213
suite('Schema Request Handler Tests', () => {
1314
suite('schemaRequestHandler', () => {
@@ -23,7 +24,7 @@ suite('Schema Request Handler Tests', () => {
2324
});
2425
test('Should care Win URI', async () => {
2526
const connection = <IConnection>{};
26-
const resultPromise = schemaRequestHandler(connection, 'c:\\some\\window\\path\\scheme.json');
27+
const resultPromise = schemaRequestHandler(connection, 'c:\\some\\window\\path\\scheme.json', [], URI.parse(''), false);
2728
assert.ok(readFileStub.calledOnceWith('c:\\some\\window\\path\\scheme.json'));
2829
readFileStub.callArgWith(2, undefined, '{some: "json"}');
2930
const result = await resultPromise;
@@ -32,7 +33,7 @@ suite('Schema Request Handler Tests', () => {
3233

3334
test('UNIX URI should works', async () => {
3435
const connection = <IConnection>{};
35-
const resultPromise = schemaRequestHandler(connection, '/some/unix/path/');
36+
const resultPromise = schemaRequestHandler(connection, '/some/unix/path/', [], URI.parse(''), false);
3637
readFileStub.callArgWith(2, undefined, '{some: "json"}');
3738
const result = await resultPromise;
3839
assert.equal(result, '{some: "json"}');

0 commit comments

Comments
 (0)