@actions/http-client 1.0.4 → 1.0.8
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.
- package/README.md +7 -1
- package/RELEASES.md +16 -0
- package/auth.js +5 -2
- package/index.d.ts +14 -10
- package/index.js +83 -28
- package/interfaces.d.ts +7 -2
- package/interfaces.js +0 -1
- package/package.json +11 -7
- package/proxy.js +7 -6
package/README.md
CHANGED
|
@@ -18,6 +18,8 @@ A lightweight HTTP client optimized for use with actions, TypeScript with generi
|
|
|
18
18
|
- Basic, Bearer and PAT Support out of the box. Extensible handlers for others.
|
|
19
19
|
- Redirects supported
|
|
20
20
|
|
|
21
|
+
Features and releases [here](./RELEASES.md)
|
|
22
|
+
|
|
21
23
|
## Install
|
|
22
24
|
|
|
23
25
|
```
|
|
@@ -49,7 +51,11 @@ export NODE_DEBUG=http
|
|
|
49
51
|
|
|
50
52
|
## Node support
|
|
51
53
|
|
|
52
|
-
The http-client is built using the latest LTS version of Node 12.
|
|
54
|
+
The http-client is built using the latest LTS version of Node 12. It may work on previous node LTS versions but it's tested and officially supported on Node12+.
|
|
55
|
+
|
|
56
|
+
## Support and Versioning
|
|
57
|
+
|
|
58
|
+
We follow semver and will hold compatibility between major versions and increment the minor version with new features and capabilities (while holding compat).
|
|
53
59
|
|
|
54
60
|
## Contributing
|
|
55
61
|
|
package/RELEASES.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
## Releases
|
|
2
|
+
|
|
3
|
+
## 1.0.7
|
|
4
|
+
Update NPM dependencies and add 429 to the list of HttpCodes
|
|
5
|
+
|
|
6
|
+
## 1.0.6
|
|
7
|
+
Automatically sends Content-Type and Accept application/json headers for \<verb>Json() helper methods if not set in the client or parameters.
|
|
8
|
+
|
|
9
|
+
## 1.0.5
|
|
10
|
+
Adds \<verb>Json() helper methods for json over http scenarios.
|
|
11
|
+
|
|
12
|
+
## 1.0.4
|
|
13
|
+
Started to add \<verb>Json() helper methods. Do not use this release for that. Use >= 1.0.5 since there was an issue with types.
|
|
14
|
+
|
|
15
|
+
## 1.0.1 to 1.0.3
|
|
16
|
+
Adds proxy support.
|
package/auth.js
CHANGED
|
@@ -6,7 +6,9 @@ class BasicCredentialHandler {
|
|
|
6
6
|
this.password = password;
|
|
7
7
|
}
|
|
8
8
|
prepareRequest(options) {
|
|
9
|
-
options.headers['Authorization'] =
|
|
9
|
+
options.headers['Authorization'] =
|
|
10
|
+
'Basic ' +
|
|
11
|
+
Buffer.from(this.username + ':' + this.password).toString('base64');
|
|
10
12
|
}
|
|
11
13
|
// This handler cannot handle 401
|
|
12
14
|
canHandleAuthentication(response) {
|
|
@@ -42,7 +44,8 @@ class PersonalAccessTokenCredentialHandler {
|
|
|
42
44
|
// currently implements pre-authorization
|
|
43
45
|
// TODO: support preAuth = false where it hooks on 401
|
|
44
46
|
prepareRequest(options) {
|
|
45
|
-
options.headers['Authorization'] =
|
|
47
|
+
options.headers['Authorization'] =
|
|
48
|
+
'Basic ' + Buffer.from('PAT:' + this.token).toString('base64');
|
|
46
49
|
}
|
|
47
50
|
// This handler cannot handle 401
|
|
48
51
|
canHandleAuthentication(response) {
|
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import http = require(
|
|
2
|
+
import http = require('http');
|
|
3
3
|
import ifm = require('./interfaces');
|
|
4
4
|
export declare enum HttpCodes {
|
|
5
5
|
OK = 200,
|
|
@@ -23,12 +23,20 @@ export declare enum HttpCodes {
|
|
|
23
23
|
RequestTimeout = 408,
|
|
24
24
|
Conflict = 409,
|
|
25
25
|
Gone = 410,
|
|
26
|
+
TooManyRequests = 429,
|
|
26
27
|
InternalServerError = 500,
|
|
27
28
|
NotImplemented = 501,
|
|
28
29
|
BadGateway = 502,
|
|
29
30
|
ServiceUnavailable = 503,
|
|
30
31
|
GatewayTimeout = 504
|
|
31
32
|
}
|
|
33
|
+
export declare enum Headers {
|
|
34
|
+
Accept = "accept",
|
|
35
|
+
ContentType = "content-type"
|
|
36
|
+
}
|
|
37
|
+
export declare enum MediaTypes {
|
|
38
|
+
ApplicationJson = "application/json"
|
|
39
|
+
}
|
|
32
40
|
/**
|
|
33
41
|
* Returns the proxy URL, depending upon the supplied url and proxy environment variables.
|
|
34
42
|
* @param serverUrl The server URL where the request will be sent. For example, https://api.github.com
|
|
@@ -39,11 +47,6 @@ export declare class HttpClientResponse implements ifm.IHttpClientResponse {
|
|
|
39
47
|
message: http.IncomingMessage;
|
|
40
48
|
readBody(): Promise<string>;
|
|
41
49
|
}
|
|
42
|
-
export interface ITypedResponse<T> {
|
|
43
|
-
statusCode: number;
|
|
44
|
-
result: T | null;
|
|
45
|
-
headers: Object;
|
|
46
|
-
}
|
|
47
50
|
export declare function isHttps(requestUrl: string): boolean;
|
|
48
51
|
export declare class HttpClient {
|
|
49
52
|
userAgent: string | undefined;
|
|
@@ -73,10 +76,10 @@ export declare class HttpClient {
|
|
|
73
76
|
* Gets a typed object from an endpoint
|
|
74
77
|
* Be aware that not found returns a null. Other errors (4xx, 5xx) reject the promise
|
|
75
78
|
*/
|
|
76
|
-
getJson<T>(requestUrl: string, additionalHeaders?: ifm.IHeaders): Promise<ITypedResponse<T>>;
|
|
77
|
-
postJson<T>(requestUrl: string, obj:
|
|
78
|
-
putJson<T>(requestUrl: string, obj:
|
|
79
|
-
patchJson<T>(requestUrl: string, obj:
|
|
79
|
+
getJson<T>(requestUrl: string, additionalHeaders?: ifm.IHeaders): Promise<ifm.ITypedResponse<T>>;
|
|
80
|
+
postJson<T>(requestUrl: string, obj: any, additionalHeaders?: ifm.IHeaders): Promise<ifm.ITypedResponse<T>>;
|
|
81
|
+
putJson<T>(requestUrl: string, obj: any, additionalHeaders?: ifm.IHeaders): Promise<ifm.ITypedResponse<T>>;
|
|
82
|
+
patchJson<T>(requestUrl: string, obj: any, additionalHeaders?: ifm.IHeaders): Promise<ifm.ITypedResponse<T>>;
|
|
80
83
|
/**
|
|
81
84
|
* Makes a raw http request.
|
|
82
85
|
* All other methods such as get, post, patch, and request ultimately call this.
|
|
@@ -108,6 +111,7 @@ export declare class HttpClient {
|
|
|
108
111
|
getAgent(serverUrl: string): http.Agent;
|
|
109
112
|
private _prepareRequest;
|
|
110
113
|
private _mergeHeaders;
|
|
114
|
+
private _getExistingOrDefaultHeader;
|
|
111
115
|
private _getAgent;
|
|
112
116
|
private _performExponentialBackoff;
|
|
113
117
|
private static dateTimeDeserializer;
|
package/index.js
CHANGED
|
@@ -28,12 +28,22 @@ var HttpCodes;
|
|
|
28
28
|
HttpCodes[HttpCodes["RequestTimeout"] = 408] = "RequestTimeout";
|
|
29
29
|
HttpCodes[HttpCodes["Conflict"] = 409] = "Conflict";
|
|
30
30
|
HttpCodes[HttpCodes["Gone"] = 410] = "Gone";
|
|
31
|
+
HttpCodes[HttpCodes["TooManyRequests"] = 429] = "TooManyRequests";
|
|
31
32
|
HttpCodes[HttpCodes["InternalServerError"] = 500] = "InternalServerError";
|
|
32
33
|
HttpCodes[HttpCodes["NotImplemented"] = 501] = "NotImplemented";
|
|
33
34
|
HttpCodes[HttpCodes["BadGateway"] = 502] = "BadGateway";
|
|
34
35
|
HttpCodes[HttpCodes["ServiceUnavailable"] = 503] = "ServiceUnavailable";
|
|
35
36
|
HttpCodes[HttpCodes["GatewayTimeout"] = 504] = "GatewayTimeout";
|
|
36
37
|
})(HttpCodes = exports.HttpCodes || (exports.HttpCodes = {}));
|
|
38
|
+
var Headers;
|
|
39
|
+
(function (Headers) {
|
|
40
|
+
Headers["Accept"] = "accept";
|
|
41
|
+
Headers["ContentType"] = "content-type";
|
|
42
|
+
})(Headers = exports.Headers || (exports.Headers = {}));
|
|
43
|
+
var MediaTypes;
|
|
44
|
+
(function (MediaTypes) {
|
|
45
|
+
MediaTypes["ApplicationJson"] = "application/json";
|
|
46
|
+
})(MediaTypes = exports.MediaTypes || (exports.MediaTypes = {}));
|
|
37
47
|
/**
|
|
38
48
|
* Returns the proxy URL, depending upon the supplied url and proxy environment variables.
|
|
39
49
|
* @param serverUrl The server URL where the request will be sent. For example, https://api.github.com
|
|
@@ -43,8 +53,18 @@ function getProxyUrl(serverUrl) {
|
|
|
43
53
|
return proxyUrl ? proxyUrl.href : '';
|
|
44
54
|
}
|
|
45
55
|
exports.getProxyUrl = getProxyUrl;
|
|
46
|
-
const HttpRedirectCodes = [
|
|
47
|
-
|
|
56
|
+
const HttpRedirectCodes = [
|
|
57
|
+
HttpCodes.MovedPermanently,
|
|
58
|
+
HttpCodes.ResourceMoved,
|
|
59
|
+
HttpCodes.SeeOther,
|
|
60
|
+
HttpCodes.TemporaryRedirect,
|
|
61
|
+
HttpCodes.PermanentRedirect
|
|
62
|
+
];
|
|
63
|
+
const HttpResponseRetryCodes = [
|
|
64
|
+
HttpCodes.BadGateway,
|
|
65
|
+
HttpCodes.ServiceUnavailable,
|
|
66
|
+
HttpCodes.GatewayTimeout
|
|
67
|
+
];
|
|
48
68
|
const RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD'];
|
|
49
69
|
const ExponentialBackoffCeiling = 10;
|
|
50
70
|
const ExponentialBackoffTimeSlice = 5;
|
|
@@ -136,22 +156,29 @@ class HttpClient {
|
|
|
136
156
|
* Gets a typed object from an endpoint
|
|
137
157
|
* Be aware that not found returns a null. Other errors (4xx, 5xx) reject the promise
|
|
138
158
|
*/
|
|
139
|
-
async getJson(requestUrl, additionalHeaders) {
|
|
159
|
+
async getJson(requestUrl, additionalHeaders = {}) {
|
|
160
|
+
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
|
|
140
161
|
let res = await this.get(requestUrl, additionalHeaders);
|
|
141
162
|
return this._processResponse(res, this.requestOptions);
|
|
142
163
|
}
|
|
143
|
-
async postJson(requestUrl, obj, additionalHeaders) {
|
|
164
|
+
async postJson(requestUrl, obj, additionalHeaders = {}) {
|
|
144
165
|
let data = JSON.stringify(obj, null, 2);
|
|
166
|
+
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
|
|
167
|
+
additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);
|
|
145
168
|
let res = await this.post(requestUrl, data, additionalHeaders);
|
|
146
169
|
return this._processResponse(res, this.requestOptions);
|
|
147
170
|
}
|
|
148
|
-
async putJson(requestUrl, obj, additionalHeaders) {
|
|
171
|
+
async putJson(requestUrl, obj, additionalHeaders = {}) {
|
|
149
172
|
let data = JSON.stringify(obj, null, 2);
|
|
173
|
+
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
|
|
174
|
+
additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);
|
|
150
175
|
let res = await this.put(requestUrl, data, additionalHeaders);
|
|
151
176
|
return this._processResponse(res, this.requestOptions);
|
|
152
177
|
}
|
|
153
|
-
async patchJson(requestUrl, obj, additionalHeaders) {
|
|
178
|
+
async patchJson(requestUrl, obj, additionalHeaders = {}) {
|
|
154
179
|
let data = JSON.stringify(obj, null, 2);
|
|
180
|
+
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
|
|
181
|
+
additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);
|
|
155
182
|
let res = await this.patch(requestUrl, data, additionalHeaders);
|
|
156
183
|
return this._processResponse(res, this.requestOptions);
|
|
157
184
|
}
|
|
@@ -162,18 +189,22 @@ class HttpClient {
|
|
|
162
189
|
*/
|
|
163
190
|
async request(verb, requestUrl, data, headers) {
|
|
164
191
|
if (this._disposed) {
|
|
165
|
-
throw new Error(
|
|
192
|
+
throw new Error('Client has already been disposed.');
|
|
166
193
|
}
|
|
167
194
|
let parsedUrl = url.parse(requestUrl);
|
|
168
195
|
let info = this._prepareRequest(verb, parsedUrl, headers);
|
|
169
196
|
// Only perform retries on reads since writes may not be idempotent.
|
|
170
|
-
let maxTries =
|
|
197
|
+
let maxTries = this._allowRetries && RetryableHttpVerbs.indexOf(verb) != -1
|
|
198
|
+
? this._maxRetries + 1
|
|
199
|
+
: 1;
|
|
171
200
|
let numTries = 0;
|
|
172
201
|
let response;
|
|
173
202
|
while (numTries < maxTries) {
|
|
174
203
|
response = await this.requestRaw(info, data);
|
|
175
204
|
// Check if it's an authentication challenge
|
|
176
|
-
if (response &&
|
|
205
|
+
if (response &&
|
|
206
|
+
response.message &&
|
|
207
|
+
response.message.statusCode === HttpCodes.Unauthorized) {
|
|
177
208
|
let authenticationHandler;
|
|
178
209
|
for (let i = 0; i < this.handlers.length; i++) {
|
|
179
210
|
if (this.handlers[i].canHandleAuthentication(response)) {
|
|
@@ -191,21 +222,32 @@ class HttpClient {
|
|
|
191
222
|
}
|
|
192
223
|
}
|
|
193
224
|
let redirectsRemaining = this._maxRedirects;
|
|
194
|
-
while (HttpRedirectCodes.indexOf(response.message.statusCode) != -1
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
const redirectUrl = response.message.headers[
|
|
225
|
+
while (HttpRedirectCodes.indexOf(response.message.statusCode) != -1 &&
|
|
226
|
+
this._allowRedirects &&
|
|
227
|
+
redirectsRemaining > 0) {
|
|
228
|
+
const redirectUrl = response.message.headers['location'];
|
|
198
229
|
if (!redirectUrl) {
|
|
199
230
|
// if there's no location to redirect to, we won't
|
|
200
231
|
break;
|
|
201
232
|
}
|
|
202
233
|
let parsedRedirectUrl = url.parse(redirectUrl);
|
|
203
|
-
if (parsedUrl.protocol == 'https:' &&
|
|
204
|
-
|
|
234
|
+
if (parsedUrl.protocol == 'https:' &&
|
|
235
|
+
parsedUrl.protocol != parsedRedirectUrl.protocol &&
|
|
236
|
+
!this._allowRedirectDowngrade) {
|
|
237
|
+
throw new Error('Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.');
|
|
205
238
|
}
|
|
206
239
|
// we need to finish reading the response before reassigning response
|
|
207
240
|
// which will leak the open socket.
|
|
208
241
|
await response.readBody();
|
|
242
|
+
// strip authorization header if redirected to a different hostname
|
|
243
|
+
if (parsedRedirectUrl.hostname !== parsedUrl.hostname) {
|
|
244
|
+
for (let header in headers) {
|
|
245
|
+
// header names are case insensitive
|
|
246
|
+
if (header.toLowerCase() === 'authorization') {
|
|
247
|
+
delete headers[header];
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
209
251
|
// let's make the request with the new redirectUrl
|
|
210
252
|
info = this._prepareRequest(verb, parsedRedirectUrl, headers);
|
|
211
253
|
response = await this.requestRaw(info, data);
|
|
@@ -256,8 +298,8 @@ class HttpClient {
|
|
|
256
298
|
*/
|
|
257
299
|
requestRawWithCallback(info, data, onResult) {
|
|
258
300
|
let socket;
|
|
259
|
-
if (typeof
|
|
260
|
-
info.options.headers[
|
|
301
|
+
if (typeof data === 'string') {
|
|
302
|
+
info.options.headers['Content-Length'] = Buffer.byteLength(data, 'utf8');
|
|
261
303
|
}
|
|
262
304
|
let callbackCalled = false;
|
|
263
305
|
let handleResult = (err, res) => {
|
|
@@ -270,7 +312,7 @@ class HttpClient {
|
|
|
270
312
|
let res = new HttpClientResponse(msg);
|
|
271
313
|
handleResult(null, res);
|
|
272
314
|
});
|
|
273
|
-
req.on('socket',
|
|
315
|
+
req.on('socket', sock => {
|
|
274
316
|
socket = sock;
|
|
275
317
|
});
|
|
276
318
|
// If we ever get disconnected, we want the socket to timeout eventually
|
|
@@ -285,10 +327,10 @@ class HttpClient {
|
|
|
285
327
|
// res should have headers
|
|
286
328
|
handleResult(err, null);
|
|
287
329
|
});
|
|
288
|
-
if (data && typeof
|
|
330
|
+
if (data && typeof data === 'string') {
|
|
289
331
|
req.write(data, 'utf8');
|
|
290
332
|
}
|
|
291
|
-
if (data && typeof
|
|
333
|
+
if (data && typeof data !== 'string') {
|
|
292
334
|
data.on('close', function () {
|
|
293
335
|
req.end();
|
|
294
336
|
});
|
|
@@ -315,29 +357,40 @@ class HttpClient {
|
|
|
315
357
|
const defaultPort = usingSsl ? 443 : 80;
|
|
316
358
|
info.options = {};
|
|
317
359
|
info.options.host = info.parsedUrl.hostname;
|
|
318
|
-
info.options.port = info.parsedUrl.port
|
|
319
|
-
|
|
360
|
+
info.options.port = info.parsedUrl.port
|
|
361
|
+
? parseInt(info.parsedUrl.port)
|
|
362
|
+
: defaultPort;
|
|
363
|
+
info.options.path =
|
|
364
|
+
(info.parsedUrl.pathname || '') + (info.parsedUrl.search || '');
|
|
320
365
|
info.options.method = method;
|
|
321
366
|
info.options.headers = this._mergeHeaders(headers);
|
|
322
367
|
if (this.userAgent != null) {
|
|
323
|
-
info.options.headers[
|
|
368
|
+
info.options.headers['user-agent'] = this.userAgent;
|
|
324
369
|
}
|
|
325
370
|
info.options.agent = this._getAgent(info.parsedUrl);
|
|
326
371
|
// gives handlers an opportunity to participate
|
|
327
372
|
if (this.handlers) {
|
|
328
|
-
this.handlers.forEach(
|
|
373
|
+
this.handlers.forEach(handler => {
|
|
329
374
|
handler.prepareRequest(info.options);
|
|
330
375
|
});
|
|
331
376
|
}
|
|
332
377
|
return info;
|
|
333
378
|
}
|
|
334
379
|
_mergeHeaders(headers) {
|
|
335
|
-
const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => (c[k.toLowerCase()] = obj[k], c), {});
|
|
380
|
+
const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {});
|
|
336
381
|
if (this.requestOptions && this.requestOptions.headers) {
|
|
337
382
|
return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers));
|
|
338
383
|
}
|
|
339
384
|
return lowercaseKeys(headers || {});
|
|
340
385
|
}
|
|
386
|
+
_getExistingOrDefaultHeader(additionalHeaders, header, _default) {
|
|
387
|
+
const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {});
|
|
388
|
+
let clientHeader;
|
|
389
|
+
if (this.requestOptions && this.requestOptions.headers) {
|
|
390
|
+
clientHeader = lowercaseKeys(this.requestOptions.headers)[header];
|
|
391
|
+
}
|
|
392
|
+
return additionalHeaders[header] || clientHeader || _default;
|
|
393
|
+
}
|
|
341
394
|
_getAgent(parsedUrl) {
|
|
342
395
|
let agent;
|
|
343
396
|
let proxyUrl = pm.getProxyUrl(parsedUrl);
|
|
@@ -369,7 +422,7 @@ class HttpClient {
|
|
|
369
422
|
proxyAuth: proxyUrl.auth,
|
|
370
423
|
host: proxyUrl.hostname,
|
|
371
424
|
port: proxyUrl.port
|
|
372
|
-
}
|
|
425
|
+
}
|
|
373
426
|
};
|
|
374
427
|
let tunnelAgent;
|
|
375
428
|
const overHttps = proxyUrl.protocol === 'https:';
|
|
@@ -396,7 +449,9 @@ class HttpClient {
|
|
|
396
449
|
// we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process
|
|
397
450
|
// http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options
|
|
398
451
|
// we have to cast it to any and change it directly
|
|
399
|
-
agent.options = Object.assign(agent.options || {}, {
|
|
452
|
+
agent.options = Object.assign(agent.options || {}, {
|
|
453
|
+
rejectUnauthorized: false
|
|
454
|
+
});
|
|
400
455
|
}
|
|
401
456
|
return agent;
|
|
402
457
|
}
|
|
@@ -457,7 +512,7 @@ class HttpClient {
|
|
|
457
512
|
msg = contents;
|
|
458
513
|
}
|
|
459
514
|
else {
|
|
460
|
-
msg =
|
|
515
|
+
msg = 'Failed request: (' + statusCode + ')';
|
|
461
516
|
}
|
|
462
517
|
let err = new Error(msg);
|
|
463
518
|
// attach statusCode and body obj (if available) to the error object
|
package/interfaces.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import http = require(
|
|
3
|
-
import url = require(
|
|
2
|
+
import http = require('http');
|
|
3
|
+
import url = require('url');
|
|
4
4
|
export interface IHeaders {
|
|
5
5
|
[key: string]: any;
|
|
6
6
|
}
|
|
@@ -43,3 +43,8 @@ export interface IRequestOptions {
|
|
|
43
43
|
allowRetries?: boolean;
|
|
44
44
|
maxRetries?: number;
|
|
45
45
|
}
|
|
46
|
+
export interface ITypedResponse<T> {
|
|
47
|
+
statusCode: number;
|
|
48
|
+
result: T | null;
|
|
49
|
+
headers: Object;
|
|
50
|
+
}
|
package/interfaces.js
CHANGED
package/package.json
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@actions/http-client",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "Actions Http Client",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "rm -Rf ./_out && tsc && cp package*.json ./_out && cp *.md ./_out && cp LICENSE ./_out && cp actions.png ./_out",
|
|
8
|
-
"test": "jest"
|
|
8
|
+
"test": "jest",
|
|
9
|
+
"format": "prettier --write *.ts && prettier --write **/*.ts",
|
|
10
|
+
"format-check": "prettier --check *.ts && prettier --check **/*.ts",
|
|
11
|
+
"audit-check": "npm audit --audit-level=moderate"
|
|
9
12
|
},
|
|
10
13
|
"repository": {
|
|
11
14
|
"type": "git",
|
|
@@ -22,12 +25,13 @@
|
|
|
22
25
|
},
|
|
23
26
|
"homepage": "https://github.com/actions/http-client#readme",
|
|
24
27
|
"devDependencies": {
|
|
25
|
-
"@types/jest": "^
|
|
26
|
-
"@types/node": "^12.12.
|
|
27
|
-
"jest": "^
|
|
28
|
+
"@types/jest": "^25.1.4",
|
|
29
|
+
"@types/node": "^12.12.31",
|
|
30
|
+
"jest": "^25.1.0",
|
|
31
|
+
"prettier": "^2.0.4",
|
|
28
32
|
"proxy": "^1.0.1",
|
|
29
|
-
"ts-jest": "^
|
|
30
|
-
"typescript": "^3.
|
|
33
|
+
"ts-jest": "^25.2.1",
|
|
34
|
+
"typescript": "^3.8.3"
|
|
31
35
|
},
|
|
32
36
|
"dependencies": {
|
|
33
37
|
"tunnel": "0.0.6"
|
package/proxy.js
CHANGED
|
@@ -9,12 +9,10 @@ function getProxyUrl(reqUrl) {
|
|
|
9
9
|
}
|
|
10
10
|
let proxyVar;
|
|
11
11
|
if (usingSsl) {
|
|
12
|
-
proxyVar = process.env[
|
|
13
|
-
process.env["HTTPS_PROXY"];
|
|
12
|
+
proxyVar = process.env['https_proxy'] || process.env['HTTPS_PROXY'];
|
|
14
13
|
}
|
|
15
14
|
else {
|
|
16
|
-
proxyVar = process.env[
|
|
17
|
-
process.env["HTTP_PROXY"];
|
|
15
|
+
proxyVar = process.env['http_proxy'] || process.env['HTTP_PROXY'];
|
|
18
16
|
}
|
|
19
17
|
if (proxyVar) {
|
|
20
18
|
proxyUrl = url.parse(proxyVar);
|
|
@@ -26,7 +24,7 @@ function checkBypass(reqUrl) {
|
|
|
26
24
|
if (!reqUrl.hostname) {
|
|
27
25
|
return false;
|
|
28
26
|
}
|
|
29
|
-
let noProxy = process.env[
|
|
27
|
+
let noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || '';
|
|
30
28
|
if (!noProxy) {
|
|
31
29
|
return false;
|
|
32
30
|
}
|
|
@@ -47,7 +45,10 @@ function checkBypass(reqUrl) {
|
|
|
47
45
|
upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`);
|
|
48
46
|
}
|
|
49
47
|
// Compare request host against noproxy
|
|
50
|
-
for (let upperNoProxyItem of noProxy
|
|
48
|
+
for (let upperNoProxyItem of noProxy
|
|
49
|
+
.split(',')
|
|
50
|
+
.map(x => x.trim().toUpperCase())
|
|
51
|
+
.filter(x => x)) {
|
|
51
52
|
if (upperReqHosts.some(x => x === upperNoProxyItem)) {
|
|
52
53
|
return true;
|
|
53
54
|
}
|