Skip to content

Commit 5931367

Browse files
committed
fix gitignore
1 parent 79d4cf5 commit 5931367

12 files changed

+2769
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
lib/
2+
node_modules/

.npmignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.vscode/
2+
lib/test/
3+
lib/*.map
4+
src/
5+
.eslintrc
6+
.gitignore

LICENSE.md

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) Microsoft
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

package.json

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"name": "request-light",
3+
"version": "0.0.1",
4+
"description": "Lightweight request library. Promise based, with proxy support.",
5+
"main": "./lib/main.js",
6+
"typings": "./lib/main",
7+
"author": "Microsoft Corporation",
8+
"repository": {
9+
"type": "git",
10+
"url": "https://github.com/Microsoft/node-request-light"
11+
},
12+
"license": "MIT",
13+
"bugs": {
14+
"url": "https://github.com/Microsoft/node-request-light/issues"
15+
},
16+
"devDependencies": {
17+
"mocha": "^2.4.5",
18+
"typescript": "^1.8.9"
19+
},
20+
"dependencies": {
21+
"http-proxy-agent": "^0.2.6",
22+
"https-proxy-agent": "^0.3.5",
23+
"vscode-nls": "^1.0.4"
24+
},
25+
"scripts": {
26+
"prepublish": "tsc -p ./src",
27+
"compile": "tsc -p ./src",
28+
"watch": "tsc -w -p ./src"
29+
}
30+
}

src/main.ts

+216
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
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+
6+
'use strict';
7+
8+
import { Url, parse as parseUrl } from 'url';
9+
import https = require('https');
10+
import http = require('http');
11+
import HttpProxyAgent = require('http-proxy-agent');
12+
import HttpsProxyAgent = require('https-proxy-agent');
13+
14+
import * as nls from 'vscode-nls';
15+
const localize = nls.loadMessageBundle();
16+
17+
export interface IXHROptions {
18+
type?: string;
19+
url?: string;
20+
user?: string;
21+
password?: string;
22+
headers?: any;
23+
timeout?: number;
24+
data?: any;
25+
agent?: any;
26+
strictSSL?: boolean;
27+
responseType?: string;
28+
followRedirects?: number;
29+
}
30+
31+
export interface IXHRResponse {
32+
responseText: string;
33+
status: number;
34+
}
35+
36+
let proxyUrl: string = null;
37+
let strictSSL: boolean = true;
38+
39+
export function configure(_proxyUrl: string, _strictSSL: boolean): void {
40+
proxyUrl = _proxyUrl;
41+
strictSSL = _strictSSL;
42+
}
43+
44+
export function xhr(options: IXHROptions): Promise<IXHRResponse> {
45+
const agent = getProxyAgent(options.url, { proxyUrl, strictSSL });
46+
options = assign({}, options);
47+
options = assign(options, { agent, strictSSL });
48+
if (typeof options.followRedirects !== 'number') {
49+
options.followRedirects = 5;
50+
}
51+
52+
return request(options).then(result => new Promise<IXHRResponse>((c, e) => {
53+
let res = result.res;
54+
let data: string[] = [];
55+
res.on('data', c => data.push(c));
56+
res.on('end', () => {
57+
if (options.followRedirects > 0 && (res.statusCode >= 300 && res.statusCode <= 303 || res.statusCode === 307)) {
58+
let location = res.headers['location'];
59+
if (location) {
60+
let newOptions = {
61+
type: options.type, url: location, user: options.user, password: options.password, responseType: options.responseType, headers: options.headers,
62+
timeout: options.timeout, followRedirects: options.followRedirects - 1, data: options.data
63+
};
64+
xhr(newOptions).then(c, e);
65+
return;
66+
}
67+
}
68+
69+
let response: IXHRResponse = {
70+
responseText: data.join(''),
71+
status: res.statusCode
72+
};
73+
74+
if ((res.statusCode >= 200 && res.statusCode < 300) || res.statusCode === 1223) {
75+
c(response);
76+
} else {
77+
e(response);
78+
}
79+
});
80+
}), err => {
81+
let message: string;
82+
83+
if (agent) {
84+
message = 'Unable to to connect to ' + options.url + ' through a proxy . Error: ' + err.message;
85+
} else {
86+
message = 'Unable to to connect to ' + options.url + '. Error: ' + err.message;
87+
}
88+
89+
return Promise.reject<IXHRResponse>({
90+
responseText: message,
91+
status: 404
92+
});
93+
});
94+
}
95+
96+
function assign(destination: any, ...sources: any[]): any {
97+
sources.forEach(source => Object.keys(source).forEach((key) => destination[key] = source[key]));
98+
return destination;
99+
}
100+
101+
interface IRequestResult {
102+
req: http.ClientRequest;
103+
res: http.ClientResponse;
104+
}
105+
106+
function request(options: IXHROptions): Promise<IRequestResult> {
107+
let req: http.ClientRequest;
108+
109+
return new Promise<IRequestResult>((c, e) => {
110+
let endpoint = parseUrl(options.url);
111+
112+
let opts: https.RequestOptions = {
113+
hostname: endpoint.hostname,
114+
port: endpoint.port ? parseInt(endpoint.port) : (endpoint.protocol === 'https:' ? 443 : 80),
115+
path: endpoint.path,
116+
method: options.type || 'GET',
117+
headers: options.headers,
118+
agent: options.agent,
119+
rejectUnauthorized: (typeof options.strictSSL === 'boolean') ? options.strictSSL : true
120+
};
121+
122+
if (options.user && options.password) {
123+
opts.auth = options.user + ':' + options.password;
124+
}
125+
126+
let protocol = endpoint.protocol === 'https:' ? https : http;
127+
req = protocol.request(opts, (res: http.ClientResponse) => {
128+
if (res.statusCode >= 300 && res.statusCode < 400 && options.followRedirects && options.followRedirects > 0 && res.headers['location']) {
129+
c(<any> request(assign({}, options, {
130+
url: res.headers['location'],
131+
followRedirects: options.followRedirects - 1
132+
})));
133+
} else {
134+
c({ req, res });
135+
}
136+
});
137+
req.on('error', e);
138+
139+
if (options.timeout) {
140+
req.setTimeout(options.timeout);
141+
}
142+
if (options.data) {
143+
req.write(options.data);
144+
}
145+
146+
req.end();
147+
});
148+
}
149+
150+
export function getErrorStatusDescription(status: number) : string {
151+
if (status < 400) {
152+
return void 0;
153+
}
154+
switch (status) {
155+
case 400: return localize('status.400', 'Bad request. The request cannot be fulfilled due to bad syntax.');
156+
case 401: return localize('status.401', 'Unauthorized. The server is refusing to respond.');
157+
case 403: return localize('status.403', 'Forbidden. The server is refusing to respond.');
158+
case 404: return localize('status.404', 'Not Found. The requested location could not be found.');
159+
case 405: return localize('status.405', 'Method not allowed. A request was made using a request method not supported by that location.');
160+
case 406: return localize('status.406', 'Not Acceptable. The server can only generate a response that is not accepted by the client.');
161+
case 407: return localize('status.407', 'Proxy Authentication Required. The client must first authenticate itself with the proxy.');
162+
case 408: return localize('status.408', 'Request Timeout. The server timed out waiting for the request.');
163+
case 409: return localize('status.409', 'Conflict. The request could not be completed because of a conflict in the request.');
164+
case 410: return localize('status.410', 'Gone. The requested page is no longer available.');
165+
case 411: return localize('status.411', 'Length Required. The "Content-Length" is not defined.');
166+
case 412: return localize('status.412', 'Precondition Failed. The precondition given in the request evaluated to false by the server.');
167+
case 413: return localize('status.413', 'Request Entity Too Large. The server will not accept the request, because the request entity is too large.');
168+
case 414: return localize('status.414', 'Request-URI Too Long. The server will not accept the request, because the URL is too long.');
169+
case 415: return localize('status.415', 'Unsupported Media Type. The server will not accept the request, because the media type is not supported.');
170+
case 500: return localize('status.500', 'Internal Server Error.');
171+
case 501: return localize('status.501', 'Not Implemented. The server either does not recognize the request method, or it lacks the ability to fulfill the request.');
172+
case 503: return localize('status.503', 'Service Unavailable. The server is currently unavailable (overloaded or down).');
173+
default: return localize('status.416', 'HTTP status code {0}', status);
174+
}
175+
}
176+
177+
// proxy handling
178+
179+
function getSystemProxyURI(requestURL: Url): string {
180+
if (requestURL.protocol === 'http:') {
181+
return process.env.HTTP_PROXY || process.env.http_proxy || null;
182+
} else if (requestURL.protocol === 'https:') {
183+
return process.env.HTTPS_PROXY || process.env.https_proxy || process.env.HTTP_PROXY || process.env.http_proxy || null;
184+
}
185+
186+
return null;
187+
}
188+
189+
interface IOptions {
190+
proxyUrl?: string;
191+
strictSSL?: boolean;
192+
}
193+
194+
function getProxyAgent(rawRequestURL: string, options: IOptions = {}): any {
195+
const requestURL = parseUrl(rawRequestURL);
196+
const proxyURL = options.proxyUrl || getSystemProxyURI(requestURL);
197+
198+
if (!proxyURL) {
199+
return null;
200+
}
201+
202+
const proxyEndpoint = parseUrl(proxyURL);
203+
204+
if (!/^https?:$/.test(proxyEndpoint.protocol)) {
205+
return null;
206+
}
207+
208+
const opts = {
209+
host: proxyEndpoint.hostname,
210+
port: Number(proxyEndpoint.port),
211+
auth: proxyEndpoint.auth,
212+
rejectUnauthorized: (typeof options.strictSSL === 'boolean') ? options.strictSSL : true
213+
};
214+
215+
return requestURL.protocol === 'http:' ? new HttpProxyAgent(opts) : new HttpsProxyAgent(opts);
216+
}

src/tsconfig.json

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ES5",
4+
"module": "commonjs",
5+
"moduleResolution": "node",
6+
"sourceMap": true,
7+
"declaration": true,
8+
"stripInternal": true,
9+
"outDir": "../lib"
10+
}
11+
}

src/typings/http-proxy-agent.d.ts

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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+
6+
declare module 'http-proxy-agent' {
7+
8+
interface IHttpProxyAgentOptions {
9+
host: string;
10+
port: number;
11+
auth?: string;
12+
}
13+
14+
class HttpProxyAgent {
15+
constructor(proxy: string);
16+
constructor(opts: IHttpProxyAgentOptions);
17+
}
18+
19+
export = HttpProxyAgent;
20+
}

src/typings/https-proxy-agent.d.ts

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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+
6+
declare module 'https-proxy-agent' {
7+
8+
import * as tls from 'tls';
9+
10+
interface IHttpsProxyAgentOptions extends tls.ConnectionOptions {
11+
host: string;
12+
port: number;
13+
auth?: string;
14+
secureProxy?: boolean;
15+
secureEndpoint?: boolean;
16+
}
17+
18+
class HttpsProxyAgent {
19+
constructor(proxy: string);
20+
constructor(opts: IHttpsProxyAgentOptions);
21+
}
22+
23+
export = HttpsProxyAgent;
24+
}

0 commit comments

Comments
 (0)