@theia/request 1.34.2 → 1.34.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,127 +1,127 @@
1
- /********************************************************************************
2
- * Copyright (C) 2022 TypeFox and others.
3
- *
4
- * This program and the accompanying materials are made available under the
5
- * terms of the Eclipse Public License v. 2.0 which is available at
6
- * http://www.eclipse.org/legal/epl-2.0.
7
- *
8
- * This Source Code may also be made available under the following Secondary
9
- * Licenses when the conditions for such availability set forth in the Eclipse
10
- * Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
- * with the GNU Classpath Exception which is available at
12
- * https://www.gnu.org/software/classpath/license.html.
13
- *
14
- * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
- ********************************************************************************/
16
-
17
- const textDecoder = typeof TextDecoder !== 'undefined' ? new TextDecoder() : undefined;
18
-
19
- export interface Headers {
20
- [header: string]: string;
21
- }
22
-
23
- export interface RequestOptions {
24
- type?: string;
25
- url: string;
26
- user?: string;
27
- password?: string;
28
- headers?: Headers;
29
- timeout?: number;
30
- data?: string;
31
- followRedirects?: number;
32
- proxyAuthorization?: string;
33
- }
34
-
35
- export interface RequestContext {
36
- url: string;
37
- res: {
38
- headers: Headers;
39
- statusCode?: number;
40
- };
41
- /**
42
- * Contains the data returned by the request.
43
- *
44
- * If the request was transferred from the backend to the frontend, the buffer has been compressed into a string. In every case the buffer is an {@link Uint8Array}.
45
- */
46
- buffer: Uint8Array | string;
47
- }
48
-
49
- export namespace RequestContext {
50
- export function isSuccess(context: RequestContext): boolean {
51
- return (context.res.statusCode && context.res.statusCode >= 200 && context.res.statusCode < 300) || context.res.statusCode === 1223;
52
- }
53
-
54
- function hasNoContent(context: RequestContext): boolean {
55
- return context.res.statusCode === 204;
56
- }
57
-
58
- export function asText(context: RequestContext): string {
59
- if (!isSuccess(context)) {
60
- throw new Error(`Server returned code ${context.res.statusCode}.`);
61
- }
62
- if (hasNoContent(context)) {
63
- return '';
64
- }
65
- // Ensures that the buffer is an Uint8Array
66
- context = decompress(context);
67
- if (textDecoder) {
68
- return textDecoder.decode(context.buffer as Uint8Array);
69
- } else {
70
- return context.buffer.toString();
71
- }
72
- }
73
-
74
- export function asJson<T = {}>(context: RequestContext): T {
75
- const str = asText(context);
76
- try {
77
- return JSON.parse(str);
78
- } catch (err) {
79
- err.message += ':\n' + str;
80
- throw err;
81
- }
82
- }
83
-
84
- /**
85
- * Convert the buffer to base64 before sending it to the frontend.
86
- * This reduces the amount of JSON data transferred massively.
87
- * Does nothing if the buffer is already compressed.
88
- */
89
- export function compress(context: RequestContext): RequestContext {
90
- if (context.buffer instanceof Uint8Array && Buffer !== undefined) {
91
- context.buffer = Buffer.from(context.buffer).toString('base64');
92
- }
93
- return context;
94
- }
95
-
96
- /**
97
- * Decompresses a base64 buffer into a normal array buffer
98
- * Does nothing if the buffer is not compressed.
99
- */
100
- export function decompress(context: RequestContext): RequestContext {
101
- const buffer = context.buffer;
102
- if (typeof buffer === 'string' && typeof atob === 'function') {
103
- context.buffer = Uint8Array.from(atob(buffer), c => c.charCodeAt(0));
104
- }
105
- return context;
106
- }
107
- }
108
-
109
- export interface RequestConfiguration {
110
- proxyUrl?: string;
111
- proxyAuthorization?: string;
112
- strictSSL?: boolean;
113
- }
114
- export interface RequestService {
115
- configure(config: RequestConfiguration): Promise<void>;
116
- request(options: RequestOptions, token?: CancellationToken): Promise<RequestContext>;
117
- resolveProxy(url: string): Promise<string | undefined>
118
- }
119
-
120
- export const RequestService = Symbol('RequestService');
121
- export const BackendRequestService = Symbol('BackendRequestService');
122
- export const REQUEST_SERVICE_PATH = '/services/request-service';
123
-
124
- export interface CancellationToken {
125
- readonly isCancellationRequested: boolean;
126
- readonly onCancellationRequested: (listener: () => void) => void;
127
- }
1
+ /********************************************************************************
2
+ * Copyright (C) 2022 TypeFox and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the Eclipse Public License v. 2.0 which is available at
6
+ * http://www.eclipse.org/legal/epl-2.0.
7
+ *
8
+ * This Source Code may also be made available under the following Secondary
9
+ * Licenses when the conditions for such availability set forth in the Eclipse
10
+ * Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ * with the GNU Classpath Exception which is available at
12
+ * https://www.gnu.org/software/classpath/license.html.
13
+ *
14
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
+ ********************************************************************************/
16
+
17
+ const textDecoder = typeof TextDecoder !== 'undefined' ? new TextDecoder() : undefined;
18
+
19
+ export interface Headers {
20
+ [header: string]: string;
21
+ }
22
+
23
+ export interface RequestOptions {
24
+ type?: string;
25
+ url: string;
26
+ user?: string;
27
+ password?: string;
28
+ headers?: Headers;
29
+ timeout?: number;
30
+ data?: string;
31
+ followRedirects?: number;
32
+ proxyAuthorization?: string;
33
+ }
34
+
35
+ export interface RequestContext {
36
+ url: string;
37
+ res: {
38
+ headers: Headers;
39
+ statusCode?: number;
40
+ };
41
+ /**
42
+ * Contains the data returned by the request.
43
+ *
44
+ * If the request was transferred from the backend to the frontend, the buffer has been compressed into a string. In every case the buffer is an {@link Uint8Array}.
45
+ */
46
+ buffer: Uint8Array | string;
47
+ }
48
+
49
+ export namespace RequestContext {
50
+ export function isSuccess(context: RequestContext): boolean {
51
+ return (context.res.statusCode && context.res.statusCode >= 200 && context.res.statusCode < 300) || context.res.statusCode === 1223;
52
+ }
53
+
54
+ function hasNoContent(context: RequestContext): boolean {
55
+ return context.res.statusCode === 204;
56
+ }
57
+
58
+ export function asText(context: RequestContext): string {
59
+ if (!isSuccess(context)) {
60
+ throw new Error(`Server returned code ${context.res.statusCode}.`);
61
+ }
62
+ if (hasNoContent(context)) {
63
+ return '';
64
+ }
65
+ // Ensures that the buffer is an Uint8Array
66
+ context = decompress(context);
67
+ if (textDecoder) {
68
+ return textDecoder.decode(context.buffer as Uint8Array);
69
+ } else {
70
+ return context.buffer.toString();
71
+ }
72
+ }
73
+
74
+ export function asJson<T = {}>(context: RequestContext): T {
75
+ const str = asText(context);
76
+ try {
77
+ return JSON.parse(str);
78
+ } catch (err) {
79
+ err.message += ':\n' + str;
80
+ throw err;
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Convert the buffer to base64 before sending it to the frontend.
86
+ * This reduces the amount of JSON data transferred massively.
87
+ * Does nothing if the buffer is already compressed.
88
+ */
89
+ export function compress(context: RequestContext): RequestContext {
90
+ if (context.buffer instanceof Uint8Array && Buffer !== undefined) {
91
+ context.buffer = Buffer.from(context.buffer).toString('base64');
92
+ }
93
+ return context;
94
+ }
95
+
96
+ /**
97
+ * Decompresses a base64 buffer into a normal array buffer
98
+ * Does nothing if the buffer is not compressed.
99
+ */
100
+ export function decompress(context: RequestContext): RequestContext {
101
+ const buffer = context.buffer;
102
+ if (typeof buffer === 'string' && typeof atob === 'function') {
103
+ context.buffer = Uint8Array.from(atob(buffer), c => c.charCodeAt(0));
104
+ }
105
+ return context;
106
+ }
107
+ }
108
+
109
+ export interface RequestConfiguration {
110
+ proxyUrl?: string;
111
+ proxyAuthorization?: string;
112
+ strictSSL?: boolean;
113
+ }
114
+ export interface RequestService {
115
+ configure(config: RequestConfiguration): Promise<void>;
116
+ request(options: RequestOptions, token?: CancellationToken): Promise<RequestContext>;
117
+ resolveProxy(url: string): Promise<string | undefined>
118
+ }
119
+
120
+ export const RequestService = Symbol('RequestService');
121
+ export const BackendRequestService = Symbol('BackendRequestService');
122
+ export const REQUEST_SERVICE_PATH = '/services/request-service';
123
+
124
+ export interface CancellationToken {
125
+ readonly isCancellationRequested: boolean;
126
+ readonly onCancellationRequested: (listener: () => void) => void;
127
+ }
package/src/index.ts CHANGED
@@ -1,17 +1,17 @@
1
- /********************************************************************************
2
- * Copyright (C) 2022 TypeFox and others.
3
- *
4
- * This program and the accompanying materials are made available under the
5
- * terms of the Eclipse Public License v. 2.0 which is available at
6
- * http://www.eclipse.org/legal/epl-2.0.
7
- *
8
- * This Source Code may also be made available under the following Secondary
9
- * Licenses when the conditions for such availability set forth in the Eclipse
10
- * Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
- * with the GNU Classpath Exception which is available at
12
- * https://www.gnu.org/software/classpath/license.html.
13
- *
14
- * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
- ********************************************************************************/
16
-
17
- export * from './common-request-service';
1
+ /********************************************************************************
2
+ * Copyright (C) 2022 TypeFox and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the Eclipse Public License v. 2.0 which is available at
6
+ * http://www.eclipse.org/legal/epl-2.0.
7
+ *
8
+ * This Source Code may also be made available under the following Secondary
9
+ * Licenses when the conditions for such availability set forth in the Eclipse
10
+ * Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ * with the GNU Classpath Exception which is available at
12
+ * https://www.gnu.org/software/classpath/license.html.
13
+ *
14
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
+ ********************************************************************************/
16
+
17
+ export * from './common-request-service';
@@ -1,165 +1,165 @@
1
- /********************************************************************************
2
- * Copyright (C) 2022 TypeFox and others.
3
- *
4
- * This program and the accompanying materials are made available under the
5
- * terms of the Eclipse Public License v. 2.0 which is available at
6
- * http://www.eclipse.org/legal/epl-2.0.
7
- *
8
- * This Source Code may also be made available under the following Secondary
9
- * Licenses when the conditions for such availability set forth in the Eclipse
10
- * Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
- * with the GNU Classpath Exception which is available at
12
- * https://www.gnu.org/software/classpath/license.html.
13
- *
14
- * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
- ********************************************************************************/
16
-
17
- import * as http from 'http';
18
- import * as https from 'https';
19
- import { getProxyAgent, ProxyAgent } from './proxy';
20
- import { Headers, RequestConfiguration, RequestContext, RequestOptions, RequestService, CancellationToken } from './common-request-service';
21
- import { createGunzip } from 'zlib';
22
-
23
- export interface RawRequestFunction {
24
- (options: http.RequestOptions, callback?: (res: http.IncomingMessage) => void): http.ClientRequest;
25
- }
26
-
27
- export interface NodeRequestOptions extends RequestOptions {
28
- agent?: ProxyAgent;
29
- strictSSL?: boolean;
30
- getRawRequest?(options: NodeRequestOptions): RawRequestFunction;
31
- };
32
-
33
- export class NodeRequestService implements RequestService {
34
-
35
- protected proxyUrl?: string;
36
- protected strictSSL?: boolean;
37
- protected authorization?: string;
38
-
39
- protected getNodeRequest(options: RequestOptions): RawRequestFunction {
40
- const endpoint = new URL(options.url);
41
- const module = endpoint.protocol === 'https:' ? https : http;
42
- return module.request;
43
- }
44
-
45
- protected async getProxyUrl(url: string): Promise<string | undefined> {
46
- return this.proxyUrl;
47
- }
48
-
49
- async configure(config: RequestConfiguration): Promise<void> {
50
- if (config.proxyUrl !== undefined) {
51
- this.proxyUrl = config.proxyUrl;
52
- }
53
- if (config.strictSSL !== undefined) {
54
- this.strictSSL = config.strictSSL;
55
- }
56
- if (config.proxyAuthorization !== undefined) {
57
- this.authorization = config.proxyAuthorization;
58
- }
59
- }
60
-
61
- protected async processOptions(options: NodeRequestOptions): Promise<NodeRequestOptions> {
62
- const { strictSSL } = this;
63
- options.strictSSL = options.strictSSL ?? strictSSL;
64
- const agent = options.agent ? options.agent : getProxyAgent(options.url || '', process.env, {
65
- proxyUrl: await this.getProxyUrl(options.url),
66
- strictSSL: options.strictSSL
67
- });
68
- options.agent = agent;
69
-
70
- const authorization = options.proxyAuthorization || this.authorization;
71
- if (authorization) {
72
- options.headers = {
73
- ...(options.headers || {}),
74
- 'Proxy-Authorization': authorization
75
- };
76
- }
77
-
78
- options.headers = {
79
- 'Accept-Encoding': 'gzip',
80
- ...(options.headers || {}),
81
- };
82
-
83
- return options;
84
- }
85
-
86
- request(options: NodeRequestOptions, token?: CancellationToken): Promise<RequestContext> {
87
- return new Promise(async (resolve, reject) => {
88
- options = await this.processOptions(options);
89
-
90
- const endpoint = new URL(options.url);
91
- const rawRequest = options.getRawRequest
92
- ? options.getRawRequest(options)
93
- : this.getNodeRequest(options);
94
-
95
- const opts: https.RequestOptions = {
96
- hostname: endpoint.hostname,
97
- port: endpoint.port ? parseInt(endpoint.port) : (endpoint.protocol === 'https:' ? 443 : 80),
98
- protocol: endpoint.protocol,
99
- path: endpoint.pathname + endpoint.search,
100
- method: options.type || 'GET',
101
- headers: options.headers,
102
- agent: options.agent,
103
- rejectUnauthorized: !!options.strictSSL
104
- };
105
-
106
- if (options.user && options.password) {
107
- opts.auth = options.user + ':' + options.password;
108
- }
109
-
110
- const req = rawRequest(opts, async res => {
111
- const followRedirects = options.followRedirects ?? 3;
112
- if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && followRedirects > 0 && res.headers.location) {
113
- this.request({
114
- ...options,
115
- url: res.headers.location,
116
- followRedirects: followRedirects - 1
117
- }, token).then(resolve, reject);
118
- } else {
119
- const chunks: Uint8Array[] = [];
120
-
121
- const stream = res.headers['content-encoding'] === 'gzip' ? res.pipe(createGunzip()) : res;
122
-
123
- stream.on('data', chunk => {
124
- chunks.push(chunk);
125
- });
126
-
127
- stream.on('end', () => {
128
- const buffer = Buffer.concat(chunks);
129
- resolve({
130
- url: options.url,
131
- res: {
132
- headers: res.headers as Headers,
133
- statusCode: res.statusCode
134
- },
135
- buffer
136
- });
137
- });
138
-
139
- stream.on('error', reject);
140
- }
141
- });
142
-
143
- req.on('error', reject);
144
-
145
- if (options.timeout) {
146
- req.setTimeout(options.timeout);
147
- }
148
-
149
- if (options.data) {
150
- req.write(options.data);
151
- }
152
-
153
- req.end();
154
-
155
- token?.onCancellationRequested(() => {
156
- req.abort();
157
- reject();
158
- });
159
- });
160
- }
161
-
162
- async resolveProxy(url: string): Promise<string | undefined> {
163
- return undefined;
164
- }
165
- }
1
+ /********************************************************************************
2
+ * Copyright (C) 2022 TypeFox and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the Eclipse Public License v. 2.0 which is available at
6
+ * http://www.eclipse.org/legal/epl-2.0.
7
+ *
8
+ * This Source Code may also be made available under the following Secondary
9
+ * Licenses when the conditions for such availability set forth in the Eclipse
10
+ * Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ * with the GNU Classpath Exception which is available at
12
+ * https://www.gnu.org/software/classpath/license.html.
13
+ *
14
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
+ ********************************************************************************/
16
+
17
+ import * as http from 'http';
18
+ import * as https from 'https';
19
+ import { getProxyAgent, ProxyAgent } from './proxy';
20
+ import { Headers, RequestConfiguration, RequestContext, RequestOptions, RequestService, CancellationToken } from './common-request-service';
21
+ import { createGunzip } from 'zlib';
22
+
23
+ export interface RawRequestFunction {
24
+ (options: http.RequestOptions, callback?: (res: http.IncomingMessage) => void): http.ClientRequest;
25
+ }
26
+
27
+ export interface NodeRequestOptions extends RequestOptions {
28
+ agent?: ProxyAgent;
29
+ strictSSL?: boolean;
30
+ getRawRequest?(options: NodeRequestOptions): RawRequestFunction;
31
+ };
32
+
33
+ export class NodeRequestService implements RequestService {
34
+
35
+ protected proxyUrl?: string;
36
+ protected strictSSL?: boolean;
37
+ protected authorization?: string;
38
+
39
+ protected getNodeRequest(options: RequestOptions): RawRequestFunction {
40
+ const endpoint = new URL(options.url);
41
+ const module = endpoint.protocol === 'https:' ? https : http;
42
+ return module.request;
43
+ }
44
+
45
+ protected async getProxyUrl(url: string): Promise<string | undefined> {
46
+ return this.proxyUrl;
47
+ }
48
+
49
+ async configure(config: RequestConfiguration): Promise<void> {
50
+ if (config.proxyUrl !== undefined) {
51
+ this.proxyUrl = config.proxyUrl;
52
+ }
53
+ if (config.strictSSL !== undefined) {
54
+ this.strictSSL = config.strictSSL;
55
+ }
56
+ if (config.proxyAuthorization !== undefined) {
57
+ this.authorization = config.proxyAuthorization;
58
+ }
59
+ }
60
+
61
+ protected async processOptions(options: NodeRequestOptions): Promise<NodeRequestOptions> {
62
+ const { strictSSL } = this;
63
+ options.strictSSL = options.strictSSL ?? strictSSL;
64
+ const agent = options.agent ? options.agent : getProxyAgent(options.url || '', process.env, {
65
+ proxyUrl: await this.getProxyUrl(options.url),
66
+ strictSSL: options.strictSSL
67
+ });
68
+ options.agent = agent;
69
+
70
+ const authorization = options.proxyAuthorization || this.authorization;
71
+ if (authorization) {
72
+ options.headers = {
73
+ ...(options.headers || {}),
74
+ 'Proxy-Authorization': authorization
75
+ };
76
+ }
77
+
78
+ options.headers = {
79
+ 'Accept-Encoding': 'gzip',
80
+ ...(options.headers || {}),
81
+ };
82
+
83
+ return options;
84
+ }
85
+
86
+ request(options: NodeRequestOptions, token?: CancellationToken): Promise<RequestContext> {
87
+ return new Promise(async (resolve, reject) => {
88
+ options = await this.processOptions(options);
89
+
90
+ const endpoint = new URL(options.url);
91
+ const rawRequest = options.getRawRequest
92
+ ? options.getRawRequest(options)
93
+ : this.getNodeRequest(options);
94
+
95
+ const opts: https.RequestOptions = {
96
+ hostname: endpoint.hostname,
97
+ port: endpoint.port ? parseInt(endpoint.port) : (endpoint.protocol === 'https:' ? 443 : 80),
98
+ protocol: endpoint.protocol,
99
+ path: endpoint.pathname + endpoint.search,
100
+ method: options.type || 'GET',
101
+ headers: options.headers,
102
+ agent: options.agent,
103
+ rejectUnauthorized: !!options.strictSSL
104
+ };
105
+
106
+ if (options.user && options.password) {
107
+ opts.auth = options.user + ':' + options.password;
108
+ }
109
+
110
+ const req = rawRequest(opts, async res => {
111
+ const followRedirects = options.followRedirects ?? 3;
112
+ if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && followRedirects > 0 && res.headers.location) {
113
+ this.request({
114
+ ...options,
115
+ url: res.headers.location,
116
+ followRedirects: followRedirects - 1
117
+ }, token).then(resolve, reject);
118
+ } else {
119
+ const chunks: Uint8Array[] = [];
120
+
121
+ const stream = res.headers['content-encoding'] === 'gzip' ? res.pipe(createGunzip()) : res;
122
+
123
+ stream.on('data', chunk => {
124
+ chunks.push(chunk);
125
+ });
126
+
127
+ stream.on('end', () => {
128
+ const buffer = Buffer.concat(chunks);
129
+ resolve({
130
+ url: options.url,
131
+ res: {
132
+ headers: res.headers as Headers,
133
+ statusCode: res.statusCode
134
+ },
135
+ buffer
136
+ });
137
+ });
138
+
139
+ stream.on('error', reject);
140
+ }
141
+ });
142
+
143
+ req.on('error', reject);
144
+
145
+ if (options.timeout) {
146
+ req.setTimeout(options.timeout);
147
+ }
148
+
149
+ if (options.data) {
150
+ req.write(options.data);
151
+ }
152
+
153
+ req.end();
154
+
155
+ token?.onCancellationRequested(() => {
156
+ req.abort();
157
+ reject();
158
+ });
159
+ });
160
+ }
161
+
162
+ async resolveProxy(url: string): Promise<string | undefined> {
163
+ return undefined;
164
+ }
165
+ }