@actions/http-client 1.0.10 → 2.0.1
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 +13 -19
- package/lib/auth.d.ts +26 -0
- package/lib/auth.js +81 -0
- package/lib/auth.js.map +1 -0
- package/lib/index.d.ts +123 -0
- package/lib/index.js +605 -0
- package/lib/index.js.map +1 -0
- package/lib/interfaces.d.ts +44 -0
- package/lib/interfaces.js +3 -0
- package/lib/interfaces.js.map +1 -0
- package/lib/proxy.d.ts +2 -0
- package/lib/proxy.js +61 -0
- package/lib/proxy.js.map +1 -0
- package/package.json +34 -25
- package/.github/workflows/test.yml +0 -51
- package/.prettierignore +0 -2
- package/.prettierrc.json +0 -11
- package/RELEASES.md +0 -22
- package/__tests__/auth.test.ts +0 -61
- package/__tests__/basics.test.ts +0 -375
- package/__tests__/headers.test.ts +0 -115
- package/__tests__/keepalive.test.ts +0 -79
- package/__tests__/proxy.test.ts +0 -228
- package/actions.png +0 -0
- package/auth.ts +0 -86
- package/index.ts +0 -768
- package/interfaces.ts +0 -98
- package/jest.config.js +0 -10
- package/proxy.ts +0 -60
- package/tsconfig.json +0 -15
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import * as http from 'http';
|
|
3
|
+
import * as https from 'https';
|
|
4
|
+
import { HttpClientResponse } from './index';
|
|
5
|
+
export interface HttpClient {
|
|
6
|
+
options(requestUrl: string, additionalHeaders?: http.OutgoingHttpHeaders): Promise<HttpClientResponse>;
|
|
7
|
+
get(requestUrl: string, additionalHeaders?: http.OutgoingHttpHeaders): Promise<HttpClientResponse>;
|
|
8
|
+
del(requestUrl: string, additionalHeaders?: http.OutgoingHttpHeaders): Promise<HttpClientResponse>;
|
|
9
|
+
post(requestUrl: string, data: string, additionalHeaders?: http.OutgoingHttpHeaders): Promise<HttpClientResponse>;
|
|
10
|
+
patch(requestUrl: string, data: string, additionalHeaders?: http.OutgoingHttpHeaders): Promise<HttpClientResponse>;
|
|
11
|
+
put(requestUrl: string, data: string, additionalHeaders?: http.OutgoingHttpHeaders): Promise<HttpClientResponse>;
|
|
12
|
+
sendStream(verb: string, requestUrl: string, stream: NodeJS.ReadableStream, additionalHeaders?: http.OutgoingHttpHeaders): Promise<HttpClientResponse>;
|
|
13
|
+
request(verb: string, requestUrl: string, data: string | NodeJS.ReadableStream, headers: http.OutgoingHttpHeaders): Promise<HttpClientResponse>;
|
|
14
|
+
requestRaw(info: RequestInfo, data: string | NodeJS.ReadableStream): Promise<HttpClientResponse>;
|
|
15
|
+
requestRawWithCallback(info: RequestInfo, data: string | NodeJS.ReadableStream, onResult: (err?: Error, res?: HttpClientResponse) => void): void;
|
|
16
|
+
}
|
|
17
|
+
export interface RequestHandler {
|
|
18
|
+
prepareRequest(options: http.RequestOptions): void;
|
|
19
|
+
canHandleAuthentication(response: HttpClientResponse): boolean;
|
|
20
|
+
handleAuthentication(httpClient: HttpClient, requestInfo: RequestInfo, data: string | NodeJS.ReadableStream | null): Promise<HttpClientResponse>;
|
|
21
|
+
}
|
|
22
|
+
export interface RequestInfo {
|
|
23
|
+
options: http.RequestOptions;
|
|
24
|
+
parsedUrl: URL;
|
|
25
|
+
httpModule: typeof http | typeof https;
|
|
26
|
+
}
|
|
27
|
+
export interface RequestOptions {
|
|
28
|
+
headers?: http.OutgoingHttpHeaders;
|
|
29
|
+
socketTimeout?: number;
|
|
30
|
+
ignoreSslError?: boolean;
|
|
31
|
+
allowRedirects?: boolean;
|
|
32
|
+
allowRedirectDowngrade?: boolean;
|
|
33
|
+
maxRedirects?: number;
|
|
34
|
+
maxSockets?: number;
|
|
35
|
+
keepAlive?: boolean;
|
|
36
|
+
deserializeDates?: boolean;
|
|
37
|
+
allowRetries?: boolean;
|
|
38
|
+
maxRetries?: number;
|
|
39
|
+
}
|
|
40
|
+
export interface TypedResponse<T> {
|
|
41
|
+
statusCode: number;
|
|
42
|
+
result: T | null;
|
|
43
|
+
headers: http.IncomingHttpHeaders;
|
|
44
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":""}
|
package/lib/proxy.d.ts
ADDED
package/lib/proxy.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkBypass = exports.getProxyUrl = void 0;
|
|
4
|
+
function getProxyUrl(reqUrl) {
|
|
5
|
+
const usingSsl = reqUrl.protocol === 'https:';
|
|
6
|
+
if (checkBypass(reqUrl)) {
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
9
|
+
const proxyVar = (() => {
|
|
10
|
+
if (usingSsl) {
|
|
11
|
+
return process.env['https_proxy'] || process.env['HTTPS_PROXY'];
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
return process.env['http_proxy'] || process.env['HTTP_PROXY'];
|
|
15
|
+
}
|
|
16
|
+
})();
|
|
17
|
+
if (proxyVar) {
|
|
18
|
+
return new URL(proxyVar);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.getProxyUrl = getProxyUrl;
|
|
25
|
+
function checkBypass(reqUrl) {
|
|
26
|
+
if (!reqUrl.hostname) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
const noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || '';
|
|
30
|
+
if (!noProxy) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
// Determine the request port
|
|
34
|
+
let reqPort;
|
|
35
|
+
if (reqUrl.port) {
|
|
36
|
+
reqPort = Number(reqUrl.port);
|
|
37
|
+
}
|
|
38
|
+
else if (reqUrl.protocol === 'http:') {
|
|
39
|
+
reqPort = 80;
|
|
40
|
+
}
|
|
41
|
+
else if (reqUrl.protocol === 'https:') {
|
|
42
|
+
reqPort = 443;
|
|
43
|
+
}
|
|
44
|
+
// Format the request hostname and hostname with port
|
|
45
|
+
const upperReqHosts = [reqUrl.hostname.toUpperCase()];
|
|
46
|
+
if (typeof reqPort === 'number') {
|
|
47
|
+
upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`);
|
|
48
|
+
}
|
|
49
|
+
// Compare request host against noproxy
|
|
50
|
+
for (const upperNoProxyItem of noProxy
|
|
51
|
+
.split(',')
|
|
52
|
+
.map(x => x.trim().toUpperCase())
|
|
53
|
+
.filter(x => x)) {
|
|
54
|
+
if (upperReqHosts.some(x => x === upperNoProxyItem)) {
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
exports.checkBypass = checkBypass;
|
|
61
|
+
//# sourceMappingURL=proxy.js.map
|
package/lib/proxy.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":";;;AAAA,SAAgB,WAAW,CAAC,MAAW;IACrC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAA;IAE7C,IAAI,WAAW,CAAC,MAAM,CAAC,EAAE;QACvB,OAAO,SAAS,CAAA;KACjB;IAED,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE;QACrB,IAAI,QAAQ,EAAE;YACZ,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAA;SAChE;aAAM;YACL,OAAO,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;SAC9D;IACH,CAAC,CAAC,EAAE,CAAA;IAEJ,IAAI,QAAQ,EAAE;QACZ,OAAO,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAA;KACzB;SAAM;QACL,OAAO,SAAS,CAAA;KACjB;AACH,CAAC;AApBD,kCAoBC;AAED,SAAgB,WAAW,CAAC,MAAW;IACrC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE;QACpB,OAAO,KAAK,CAAA;KACb;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,CAAA;IACxE,IAAI,CAAC,OAAO,EAAE;QACZ,OAAO,KAAK,CAAA;KACb;IAED,6BAA6B;IAC7B,IAAI,OAA2B,CAAA;IAC/B,IAAI,MAAM,CAAC,IAAI,EAAE;QACf,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;KAC9B;SAAM,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,EAAE;QACtC,OAAO,GAAG,EAAE,CAAA;KACb;SAAM,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE;QACvC,OAAO,GAAG,GAAG,CAAA;KACd;IAED,qDAAqD;IACrD,MAAM,aAAa,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAA;IACrD,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE;QAC/B,aAAa,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC,CAAA;KACrD;IAED,uCAAuC;IACvC,KAAK,MAAM,gBAAgB,IAAI,OAAO;SACnC,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;SAChC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;QACjB,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,gBAAgB,CAAC,EAAE;YACnD,OAAO,IAAI,CAAA;SACZ;KACF;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AArCD,kCAqCC"}
|
package/package.json
CHANGED
|
@@ -1,39 +1,48 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@actions/http-client",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "Actions Http Client",
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
"keywords": [
|
|
6
|
+
"github",
|
|
7
|
+
"actions",
|
|
8
|
+
"http"
|
|
9
|
+
],
|
|
10
|
+
"homepage": "https://github.com/actions/toolkit/tree/main/packages/http-client",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"main": "lib/index.js",
|
|
13
|
+
"types": "lib/index.d.ts",
|
|
14
|
+
"directories": {
|
|
15
|
+
"lib": "lib",
|
|
16
|
+
"test": "__tests__"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"lib",
|
|
20
|
+
"!.DS_Store"
|
|
21
|
+
],
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public"
|
|
12
24
|
},
|
|
13
25
|
"repository": {
|
|
14
26
|
"type": "git",
|
|
15
|
-
"url": "git+https://github.com/actions/
|
|
27
|
+
"url": "git+https://github.com/actions/toolkit.git",
|
|
28
|
+
"directory": "packages/http-client"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"audit-moderate": "npm install && npm audit --json --audit-level=moderate > audit.json",
|
|
32
|
+
"test": "echo \"Error: run tests from root\" && exit 1",
|
|
33
|
+
"build": "tsc",
|
|
34
|
+
"format": "prettier --write **/*.ts",
|
|
35
|
+
"format-check": "prettier --check **/*.ts",
|
|
36
|
+
"tsc": "tsc"
|
|
16
37
|
},
|
|
17
|
-
"keywords": [
|
|
18
|
-
"Actions",
|
|
19
|
-
"Http"
|
|
20
|
-
],
|
|
21
|
-
"author": "GitHub, Inc.",
|
|
22
|
-
"license": "MIT",
|
|
23
38
|
"bugs": {
|
|
24
|
-
"url": "https://github.com/actions/
|
|
39
|
+
"url": "https://github.com/actions/toolkit/issues"
|
|
25
40
|
},
|
|
26
|
-
"homepage": "https://github.com/actions/http-client#readme",
|
|
27
41
|
"devDependencies": {
|
|
28
|
-
"@types/
|
|
29
|
-
"
|
|
30
|
-
"jest": "^25.1.0",
|
|
31
|
-
"prettier": "^2.0.4",
|
|
32
|
-
"proxy": "^1.0.1",
|
|
33
|
-
"ts-jest": "^25.2.1",
|
|
34
|
-
"typescript": "^3.8.3"
|
|
42
|
+
"@types/tunnel": "0.0.3",
|
|
43
|
+
"proxy": "^1.0.1"
|
|
35
44
|
},
|
|
36
45
|
"dependencies": {
|
|
37
|
-
"tunnel": "0.0.6"
|
|
46
|
+
"tunnel": "^0.0.6"
|
|
38
47
|
}
|
|
39
48
|
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
name: http-tests
|
|
2
|
-
on:
|
|
3
|
-
push:
|
|
4
|
-
branches:
|
|
5
|
-
- main
|
|
6
|
-
paths-ignore:
|
|
7
|
-
- '**.md'
|
|
8
|
-
pull_request:
|
|
9
|
-
paths-ignore:
|
|
10
|
-
- '**.md'
|
|
11
|
-
|
|
12
|
-
jobs:
|
|
13
|
-
|
|
14
|
-
build:
|
|
15
|
-
name: Build
|
|
16
|
-
|
|
17
|
-
strategy:
|
|
18
|
-
matrix:
|
|
19
|
-
runs-on: [ubuntu-latest, macOS-latest, windows-latest]
|
|
20
|
-
node-version: [12.x]
|
|
21
|
-
fail-fast: false
|
|
22
|
-
|
|
23
|
-
runs-on: ${{ matrix.runs-on }}
|
|
24
|
-
|
|
25
|
-
steps:
|
|
26
|
-
- name: Checkout
|
|
27
|
-
uses: actions/checkout@v2
|
|
28
|
-
|
|
29
|
-
- name: Setup node
|
|
30
|
-
uses: actions/setup-node@v1
|
|
31
|
-
with:
|
|
32
|
-
node-version: ${{ matrix.node-version }}
|
|
33
|
-
|
|
34
|
-
- name: npm install
|
|
35
|
-
run: npm install
|
|
36
|
-
|
|
37
|
-
- name: Compile
|
|
38
|
-
run: npm run build
|
|
39
|
-
|
|
40
|
-
- name: npm test
|
|
41
|
-
run: npm test
|
|
42
|
-
|
|
43
|
-
- name: Format
|
|
44
|
-
shell: bash
|
|
45
|
-
run: npm run format-check
|
|
46
|
-
if: matrix.runs-on == 'ubuntu-latest'
|
|
47
|
-
|
|
48
|
-
- name: audit security
|
|
49
|
-
continue-on-error: true
|
|
50
|
-
run: npm audit --audit-level=moderate
|
|
51
|
-
if: matrix.runs-on == 'ubuntu-latest'
|
package/.prettierignore
DELETED
package/.prettierrc.json
DELETED
package/RELEASES.md
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
## Releases
|
|
2
|
-
|
|
3
|
-
## 1.0.9
|
|
4
|
-
Throw HttpClientError instead of a generic Error from the \<verb>Json() helper methods when the server responds with a non-successful status code.
|
|
5
|
-
|
|
6
|
-
## 1.0.8
|
|
7
|
-
Fixed security issue where a redirect (e.g. 302) to another domain would pass headers. The fix was to strip the authorization header if the hostname was different. More [details in PR #27](https://github.com/actions/http-client/pull/27)
|
|
8
|
-
|
|
9
|
-
## 1.0.7
|
|
10
|
-
Update NPM dependencies and add 429 to the list of HttpCodes
|
|
11
|
-
|
|
12
|
-
## 1.0.6
|
|
13
|
-
Automatically sends Content-Type and Accept application/json headers for \<verb>Json() helper methods if not set in the client or parameters.
|
|
14
|
-
|
|
15
|
-
## 1.0.5
|
|
16
|
-
Adds \<verb>Json() helper methods for json over http scenarios.
|
|
17
|
-
|
|
18
|
-
## 1.0.4
|
|
19
|
-
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.
|
|
20
|
-
|
|
21
|
-
## 1.0.1 to 1.0.3
|
|
22
|
-
Adds proxy support.
|
package/__tests__/auth.test.ts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import * as httpm from '../_out'
|
|
2
|
-
import * as am from '../_out/auth'
|
|
3
|
-
|
|
4
|
-
describe('auth', () => {
|
|
5
|
-
beforeEach(() => {})
|
|
6
|
-
|
|
7
|
-
afterEach(() => {})
|
|
8
|
-
|
|
9
|
-
it('does basic http get request with basic auth', async () => {
|
|
10
|
-
let bh: am.BasicCredentialHandler = new am.BasicCredentialHandler(
|
|
11
|
-
'johndoe',
|
|
12
|
-
'password'
|
|
13
|
-
)
|
|
14
|
-
let http: httpm.HttpClient = new httpm.HttpClient('http-client-tests', [bh])
|
|
15
|
-
let res: httpm.HttpClientResponse = await http.get('http://httpbin.org/get')
|
|
16
|
-
expect(res.message.statusCode).toBe(200)
|
|
17
|
-
let body: string = await res.readBody()
|
|
18
|
-
let obj: any = JSON.parse(body)
|
|
19
|
-
let auth: string = obj.headers.Authorization
|
|
20
|
-
let creds: string = Buffer.from(
|
|
21
|
-
auth.substring('Basic '.length),
|
|
22
|
-
'base64'
|
|
23
|
-
).toString()
|
|
24
|
-
expect(creds).toBe('johndoe:password')
|
|
25
|
-
expect(obj.url).toBe('http://httpbin.org/get')
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
it('does basic http get request with pat token auth', async () => {
|
|
29
|
-
let token: string = 'scbfb44vxzku5l4xgc3qfazn3lpk4awflfryc76esaiq7aypcbhs'
|
|
30
|
-
let ph: am.PersonalAccessTokenCredentialHandler = new am.PersonalAccessTokenCredentialHandler(
|
|
31
|
-
token
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
let http: httpm.HttpClient = new httpm.HttpClient('http-client-tests', [ph])
|
|
35
|
-
let res: httpm.HttpClientResponse = await http.get('http://httpbin.org/get')
|
|
36
|
-
expect(res.message.statusCode).toBe(200)
|
|
37
|
-
let body: string = await res.readBody()
|
|
38
|
-
let obj: any = JSON.parse(body)
|
|
39
|
-
let auth: string = obj.headers.Authorization
|
|
40
|
-
let creds: string = Buffer.from(
|
|
41
|
-
auth.substring('Basic '.length),
|
|
42
|
-
'base64'
|
|
43
|
-
).toString()
|
|
44
|
-
expect(creds).toBe('PAT:' + token)
|
|
45
|
-
expect(obj.url).toBe('http://httpbin.org/get')
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
it('does basic http get request with pat token auth', async () => {
|
|
49
|
-
let token: string = 'scbfb44vxzku5l4xgc3qfazn3lpk4awflfryc76esaiq7aypcbhs'
|
|
50
|
-
let ph: am.BearerCredentialHandler = new am.BearerCredentialHandler(token)
|
|
51
|
-
|
|
52
|
-
let http: httpm.HttpClient = new httpm.HttpClient('http-client-tests', [ph])
|
|
53
|
-
let res: httpm.HttpClientResponse = await http.get('http://httpbin.org/get')
|
|
54
|
-
expect(res.message.statusCode).toBe(200)
|
|
55
|
-
let body: string = await res.readBody()
|
|
56
|
-
let obj: any = JSON.parse(body)
|
|
57
|
-
let auth: string = obj.headers.Authorization
|
|
58
|
-
expect(auth).toBe('Bearer ' + token)
|
|
59
|
-
expect(obj.url).toBe('http://httpbin.org/get')
|
|
60
|
-
})
|
|
61
|
-
})
|