Comparing version 3.0.2 to 4.0.0-ts0
773
lib/http.js
@@ -1,100 +0,60 @@ | ||
'use strict'; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.HTTPError = undefined; | ||
exports.get = get; | ||
exports.post = post; | ||
exports.put = put; | ||
exports.patch = patch; | ||
exports.hdelete = hdelete; | ||
exports.stream = stream; | ||
exports.request = request; | ||
var _util = require('util'); | ||
var _util2 = _interopRequireDefault(_util); | ||
var _url = require('url'); | ||
var _url2 = _interopRequireDefault(_url); | ||
var _package = require('../package.json'); | ||
var _package2 = _interopRequireDefault(_package); | ||
var _http = require('http'); | ||
var _http2 = _interopRequireDefault(_http); | ||
var _https = require('https'); | ||
var _https2 = _interopRequireDefault(_https); | ||
var _proxy = require('./proxy'); | ||
var _proxy2 = _interopRequireDefault(_proxy); | ||
var _isStream = require('is-stream'); | ||
var _isStream2 = _interopRequireDefault(_isStream); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
require("core-js/library"); | ||
const util = require("util"); | ||
const uri = require("url"); | ||
const http = require("http"); | ||
const https = require("https"); | ||
const proxy_1 = require("./proxy"); | ||
const isStream = require("is-stream"); | ||
const pjson = require('../package.json'); | ||
const debug = require('debug')('http'); | ||
const debugHeaders = require('debug')('http:headers'); | ||
const debugBody = require('debug')('http:body'); | ||
function concat(stream) { | ||
return new Promise(resolve => { | ||
let strings = []; | ||
stream.on('data', data => strings.push(data)); | ||
stream.on('end', () => resolve(strings.join(''))); | ||
}); | ||
return new Promise(resolve => { | ||
let strings = []; | ||
stream.on('data', data => strings.push(data)); | ||
stream.on('end', () => resolve(strings.join(''))); | ||
}); | ||
} | ||
/** | ||
* @typedef {Object} HTTPRequestOptions | ||
* @property {Object.<string, string>} headers - request headers | ||
* @property {string} method - request method (GET/POST/etc) | ||
* @property {(string)} body - request body. Sets content-type to application/json and stringifies when object | ||
* @property {(boolean)} partial - do not make continuous requests while receiving a Next-Range header for GET requests | ||
* @property {(number)} port - port to use | ||
*/ | ||
function caseInsensitiveObject() { | ||
let lowercaseKey = k => typeof k === 'string' ? k.toLowerCase() : k; | ||
return new Proxy({}, { | ||
get: (t, k) => { | ||
k = lowercaseKey(k); | ||
return t[k]; | ||
}, | ||
set: (t, k, v) => { | ||
k = lowercaseKey(k); | ||
t[k] = v; | ||
return true; | ||
}, | ||
deleteProperty: (t, k) => { | ||
k = lowercaseKey(k); | ||
if (k in t) return false; | ||
return delete t[k]; | ||
}, | ||
has: function (t, k) { | ||
k = lowercaseKey(k); | ||
return k in t; | ||
} | ||
}); | ||
let lowercaseKey = (k) => (typeof k === 'string') ? k.toLowerCase() : k; | ||
return new Proxy({}, { | ||
get: (t, k) => { | ||
k = lowercaseKey(k); | ||
return t[k]; | ||
}, | ||
set: (t, k, v) => { | ||
k = lowercaseKey(k); | ||
t[k] = v; | ||
return true; | ||
}, | ||
deleteProperty: (t, k) => { | ||
k = lowercaseKey(k); | ||
if (k in t) | ||
return false; | ||
return delete t[k]; | ||
}, | ||
has: function (t, k) { | ||
k = lowercaseKey(k); | ||
return k in t; | ||
} | ||
}); | ||
} | ||
function lowercaseHeaders(headers) { | ||
let newHeaders = caseInsensitiveObject(); | ||
for (let [k, v] of Object.entries(headers)) { | ||
newHeaders[k] = v; | ||
} | ||
return newHeaders; | ||
let newHeaders = caseInsensitiveObject(); | ||
for (let [k, v] of Object.entries(headers)) { | ||
newHeaders[k] = v; | ||
} | ||
return newHeaders; | ||
} | ||
/** | ||
@@ -105,333 +65,324 @@ * Utility for simple HTTP calls | ||
class HTTP { | ||
/** | ||
* make an http GET request | ||
* @param {string} url - url or path to call | ||
* @param {HTTPRequestOptions} options | ||
* @returns {Promise} | ||
* @example | ||
* ```js | ||
* const http = require('http-call') | ||
* await http.get('https://google.com') | ||
* ``` | ||
*/ | ||
static get(url, options = {}) { | ||
return this.request(url, { ...options, method: 'GET' }); | ||
} | ||
/** | ||
* make an http POST request | ||
* @param {string} url - url or path to call | ||
* @param {HTTPRequestOptions} options | ||
* @returns {Promise} | ||
* @example | ||
* ```js | ||
* const http = require('http-call') | ||
* await http.post('https://google.com') | ||
* ``` | ||
*/ | ||
static post(url, options = {}) { | ||
return this.request(url, { ...options, method: 'POST' }); | ||
} | ||
/** | ||
* make an http PUT request | ||
* @param {string} url - url or path to call | ||
* @param {HTTPRequestOptions} options | ||
* @returns {Promise} | ||
* @example | ||
* ```js | ||
* const http = require('http-call') | ||
* await http.put('https://google.com') | ||
* ``` | ||
*/ | ||
static put(url, options = {}) { | ||
return this.request(url, { ...options, method: 'PUT' }); | ||
} | ||
/** | ||
* make an http PATCH request | ||
* @param {string} url - url or path to call | ||
* @param {HTTPRequestOptions} options | ||
* @returns {Promise} | ||
* @example | ||
* ```js | ||
* const http = require('http-call') | ||
* await http.patch('https://google.com') | ||
* ``` | ||
*/ | ||
static async patch(url, options = {}) { | ||
return this.request(url, { ...options, method: 'PATCH' }); | ||
} | ||
/** | ||
* make an http DELETE request | ||
* @param {string} url - url or path to call | ||
* @param {HTTPRequestOptions} options | ||
* @returns {Promise} | ||
* @example | ||
* ```js | ||
* const http = require('http-call') | ||
* await http.delete('https://google.com') | ||
* ``` | ||
*/ | ||
static async delete(url, options = {}) { | ||
return this.request(url, { ...options, method: 'DELETE' }); | ||
} | ||
/** | ||
* make a streaming request | ||
* @param {string} url - url or path to call | ||
* @param {HTTPRequestOptions} options | ||
* @returns {Promise} | ||
* @example | ||
* ```js | ||
* const http = require('http-call') | ||
* let {response} = await http.get('https://google.com') | ||
* response.on('data', console.log) | ||
* ``` | ||
*/ | ||
static stream(url, options = {}) { | ||
return this.request(url, { ...options, raw: true }); | ||
} | ||
static async request(url, options = {}) { | ||
let http = new this(url, options); | ||
await http._request(); | ||
return http; | ||
} | ||
static defaults(options = {}) { | ||
return class CustomHTTP extends HTTP { | ||
static get defaultOptions() { | ||
/** | ||
* make an http GET request | ||
* @param {string} url - url or path to call | ||
* @param {HTTPRequestOptions} options | ||
* @returns {Promise} | ||
* @example | ||
* ```js | ||
* const http = require('http-call') | ||
* await http.get('https://google.com') | ||
* ``` | ||
*/ | ||
static get(url, options = {}) { | ||
return this.request(url, Object.assign({}, options, { method: 'GET' })); | ||
} | ||
/** | ||
* make an http POST request | ||
* @param {string} url - url or path to call | ||
* @param {HTTPRequestOptions} options | ||
* @returns {Promise} | ||
* @example | ||
* ```js | ||
* const http = require('http-call') | ||
* await http.post('https://google.com') | ||
* ``` | ||
*/ | ||
static post(url, options = {}) { | ||
return this.request(url, Object.assign({}, options, { method: 'POST' })); | ||
} | ||
/** | ||
* make an http PUT request | ||
* @param {string} url - url or path to call | ||
* @param {HTTPRequestOptions} options | ||
* @returns {Promise} | ||
* @example | ||
* ```js | ||
* const http = require('http-call') | ||
* await http.put('https://google.com') | ||
* ``` | ||
*/ | ||
static put(url, options = {}) { | ||
return this.request(url, Object.assign({}, options, { method: 'PUT' })); | ||
} | ||
/** | ||
* make an http PATCH request | ||
* @param {string} url - url or path to call | ||
* @param {HTTPRequestOptions} options | ||
* @returns {Promise} | ||
* @example | ||
* ```js | ||
* const http = require('http-call') | ||
* await http.patch('https://google.com') | ||
* ``` | ||
*/ | ||
static patch(url, options = {}) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.request(url, Object.assign({}, options, { method: 'PATCH' })); | ||
}); | ||
} | ||
/** | ||
* make an http DELETE request | ||
* @param {string} url - url or path to call | ||
* @param {HTTPRequestOptions} options | ||
* @returns {Promise} | ||
* @example | ||
* ```js | ||
* const http = require('http-call') | ||
* await http.delete('https://google.com') | ||
* ``` | ||
*/ | ||
static delete(url, options = {}) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return this.request(url, Object.assign({}, options, { method: 'DELETE' })); | ||
}); | ||
} | ||
/** | ||
* make a streaming request | ||
* @param {string} url - url or path to call | ||
* @param {HTTPRequestOptions} options | ||
* @returns {Promise} | ||
* @example | ||
* ```js | ||
* const http = require('http-call') | ||
* let {response} = await http.get('https://google.com') | ||
* response.on('data', console.log) | ||
* ``` | ||
*/ | ||
static stream(url, options = {}) { | ||
return this.request(url, Object.assign({}, options, { raw: true })); | ||
} | ||
static request(url, options = {}) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
let http = new this(url, options); | ||
yield http._request(); | ||
return http; | ||
}); | ||
} | ||
static defaults(options = {}) { | ||
return class CustomHTTP extends HTTP { | ||
static get defaultOptions() { | ||
return Object.assign({}, super.defaultOptions, options); | ||
} | ||
}; | ||
} | ||
static get defaultOptions() { | ||
return { | ||
...super.defaultOptions, | ||
...options | ||
method: 'GET', | ||
host: 'localhost', | ||
protocol: 'https:', | ||
path: '/', | ||
raw: false, | ||
partial: false, | ||
headers: { | ||
'user-agent': `${pjson.name}/${pjson.version} node-${process.version}` | ||
} | ||
}; | ||
} | ||
}; | ||
} | ||
static get defaultOptions() { | ||
return { | ||
method: 'GET', | ||
host: 'localhost', | ||
protocol: 'https:', | ||
path: '/', | ||
raw: false, | ||
partial: false, | ||
headers: { | ||
'user-agent': `${_package2.default.name}/${_package2.default.version} node-${process.version}` | ||
} | ||
}; | ||
} | ||
// instance properties | ||
get method() { | ||
return this.options.method; | ||
} | ||
get statusCode() { | ||
if (!this.response) return 0; | ||
return this.response.statusCode; | ||
} | ||
get secure() { | ||
return this.options.protocol === 'https:'; | ||
} | ||
get url() { | ||
return `${this.options.protocol}//${this.options.host}${this.options.path}`; | ||
} | ||
set url(input) { | ||
let u = _url2.default.parse(input); | ||
this.options.protocol = u.protocol || this.options.protocol; | ||
this.options.host = u.hostname || this.constructor.defaultOptions.host || 'localhost'; | ||
this.options.path = u.path || '/'; | ||
this.options.agent = this.options.agent || _proxy2.default.agent(this.secure); | ||
this.options.port = parseInt(u.port || this.constructor.defaultOptions.port || (this.secure ? 443 : 80)); | ||
} | ||
get headers() { | ||
if (!this.response) return {}; | ||
return this.response.headers; | ||
} | ||
get partial() { | ||
if (this.method !== 'GET' || this.options.partial) return true; | ||
return !(this.headers['next-range'] && this.body instanceof Array); | ||
} | ||
constructor(url, options = {}) { | ||
this.options = { | ||
...this.constructor.defaultOptions, | ||
...options, | ||
headers: lowercaseHeaders({ | ||
...this.constructor.defaultOptions.headers, | ||
...options.headers | ||
}) | ||
}; | ||
if (!url) throw new Error('no url provided'); | ||
this.url = url; | ||
if (this.options.body) this._parseBody(this.options.body); | ||
} | ||
async _request() { | ||
this._debugRequest(); | ||
try { | ||
this.response = await this._performRequest(); | ||
} catch (err) { | ||
debug(err); | ||
return this._maybeRetry(err); | ||
} | ||
if (this._shouldParseResponseBody) await this._parse(); | ||
this._debugResponse(); | ||
if (this._responseRedirect) return this._redirect(); | ||
if (!this._responseOK) { | ||
throw new HTTPError(this); | ||
get method() { | ||
return this.options.method || 'GET'; | ||
} | ||
if (!this.partial) await this._getNextRange(); | ||
} | ||
async _redirect() { | ||
if (!this._redirectRetries) this._redirectRetries = 0; | ||
this._redirectRetries++; | ||
if (this._redirectRetries > 10) throw new Error(`Redirect loop at ${this.url}`); | ||
if (!this.headers.location) throw new Error('Redirect with no location header'); | ||
this.url = this.headers.location; | ||
await this._request(); | ||
} | ||
async _maybeRetry(err) { | ||
if (!this._errorRetries) this._errorRetries = 0; | ||
this._errorRetries++; | ||
const allowed = err => { | ||
if (this._errorRetries > 5) return false; | ||
if (!err.code) return false; | ||
if (err.code === 'ENOTFOUND') return true; | ||
return require('is-retry-allowed')(err); | ||
}; | ||
if (allowed(err)) { | ||
let noise = Math.random() * 100; | ||
await this._wait((1 << this._errorRetries) * 100 + noise); | ||
await this._request(); | ||
return; | ||
get statusCode() { | ||
if (!this.response) | ||
return 0; | ||
return this.response.statusCode || 0; | ||
} | ||
throw err; | ||
} | ||
_debugRequest() { | ||
if (this.options.agent) debug('proxy: %o', this.options.agent.options); | ||
debug('--> %s %s', this.options.method, this.url); | ||
debugHeaders(this._redactedHeaders(this.options.headers)); | ||
if (this.options.body) debugBody(this.options.body); | ||
} | ||
_debugResponse() { | ||
debug('<-- %s %s %s', this.method, this.url, this.statusCode); | ||
debugHeaders(this._redactedHeaders(this.headers)); | ||
if (this.body) debugBody(this.body); | ||
} | ||
_performRequest() { | ||
return new Promise((resolve, reject) => { | ||
this.request = this._http.request(this.options, resolve); | ||
this.request.on('error', reject); | ||
if (this.options.body && _isStream2.default.readable(this.options.body)) { | ||
this.options.body.pipe(this.request); | ||
} else { | ||
this.request.end(this.options.body); | ||
} | ||
}); | ||
} | ||
async _parse() { | ||
this.body = await concat(this.response); | ||
let json = this.headers['content-type'] === 'application/json'; | ||
if (json) this.body = JSON.parse(this.body); | ||
} | ||
_parseBody(body) { | ||
if (_isStream2.default.readable(body)) { | ||
this.options.body = body; | ||
return; | ||
get secure() { | ||
return this.options.protocol === 'https:'; | ||
} | ||
if (!this.options.headers['content-type']) { | ||
this.options.headers['content-type'] = 'application/json'; | ||
get url() { | ||
return `${this.options.protocol}//${this.options.host}${this.options.path}`; | ||
} | ||
if (this.options.headers['content-type'] === 'application/json') { | ||
this.options.body = JSON.stringify(body); | ||
} else { | ||
this.options.body = body; | ||
set url(input) { | ||
let u = uri.parse(input); | ||
this.options.protocol = u.protocol || this.options.protocol; | ||
this.options.host = u.hostname || this.constructor.defaultOptions.host || 'localhost'; | ||
this.options.path = u.path || '/'; | ||
this.options.agent = this.options.agent || proxy_1.default.agent(this.secure); | ||
this.options.port = u.port || this.constructor.defaultOptions.port || (this.secure ? 443 : 80); | ||
} | ||
this.options.headers['content-length'] = Buffer.byteLength(this.options.body).toString(); | ||
} | ||
async _getNextRange() { | ||
this.options.headers['range'] = this.headers['next-range']; | ||
let prev = this.body; | ||
await this._request(); | ||
this.body = prev.concat(this.body); | ||
} | ||
_redactedHeaders(headers) { | ||
headers = { ...headers }; | ||
if (headers.authorization) headers.authorization = '[REDACTED]'; | ||
return headers; | ||
} | ||
get _http() { | ||
return this.secure ? _https2.default : _http2.default; | ||
} | ||
get _responseOK() { | ||
if (!this.response) return false; | ||
return this.statusCode >= 200 && this.statusCode < 300; | ||
} | ||
get _responseRedirect() { | ||
if (!this.response) return false; | ||
return this.statusCode >= 300 && this.statusCode < 400; | ||
} | ||
get _shouldParseResponseBody() { | ||
return !this._responseOK || !this.options.raw && this._responseOK; | ||
} | ||
_wait(ms) { | ||
return new Promise(resolve => setTimeout(resolve, ms)); | ||
} | ||
get headers() { | ||
if (!this.response) | ||
return {}; | ||
return this.response.headers; | ||
} | ||
get partial() { | ||
if (this.method !== 'GET' || this.options.partial) | ||
return true; | ||
return !(this.headers['next-range'] && this.body instanceof Array); | ||
} | ||
constructor(url, options = {}) { | ||
this.options = (Object.assign({}, this.constructor.defaultOptions, options, { headers: lowercaseHeaders(Object.assign({}, this.constructor.defaultOptions.headers, options.headers)) })); | ||
if (!url) | ||
throw new Error('no url provided'); | ||
this.url = url; | ||
if (this.options.body) | ||
this._parseBody(this.options.body); | ||
} | ||
_request() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
this._debugRequest(); | ||
try { | ||
this.response = yield this._performRequest(); | ||
} | ||
catch (err) { | ||
debug(err); | ||
return this._maybeRetry(err); | ||
} | ||
if (this._shouldParseResponseBody) | ||
yield this._parse(); | ||
this._debugResponse(); | ||
if (this._responseRedirect) | ||
return this._redirect(); | ||
if (!this._responseOK) { | ||
throw new HTTPError(this); | ||
} | ||
if (!this.partial) | ||
yield this._getNextRange(); | ||
}); | ||
} | ||
_redirect() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (!this._redirectRetries) | ||
this._redirectRetries = 0; | ||
this._redirectRetries++; | ||
if (this._redirectRetries > 10) | ||
throw new Error(`Redirect loop at ${this.url}`); | ||
if (!this.headers.location) | ||
throw new Error('Redirect with no location header'); | ||
const location = this.headers.location; | ||
if (Array.isArray(location)) { | ||
this.url = location[0]; | ||
} | ||
else { | ||
this.url = location; | ||
} | ||
yield this._request(); | ||
}); | ||
} | ||
_maybeRetry(err) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (!this._errorRetries) | ||
this._errorRetries = 0; | ||
this._errorRetries++; | ||
const allowed = (err) => { | ||
if (this._errorRetries > 5) | ||
return false; | ||
if (!err.code) | ||
return false; | ||
if (err.code === 'ENOTFOUND') | ||
return true; | ||
return require('is-retry-allowed')(err); | ||
}; | ||
if (allowed(err)) { | ||
let noise = Math.random() * 100; | ||
yield this._wait((1 << this._errorRetries) * 100 + noise); | ||
yield this._request(); | ||
return; | ||
} | ||
throw err; | ||
}); | ||
} | ||
_debugRequest() { | ||
if (this.options.agent) | ||
debug('proxy: %o', this.options.agent); | ||
debug('--> %s %s', this.options.method, this.url); | ||
debugHeaders(this._redactedHeaders(this.options.headers)); | ||
if (this.options.body) | ||
debugBody(this.options.body); | ||
} | ||
_debugResponse() { | ||
debug('<-- %s %s %s', this.method, this.url, this.statusCode); | ||
debugHeaders(this._redactedHeaders(this.headers)); | ||
if (this.body) | ||
debugBody(this.body); | ||
} | ||
_performRequest() { | ||
return new Promise((resolve, reject) => { | ||
if (this.secure) { | ||
this.request = https.request(this.options, resolve); | ||
} | ||
else { | ||
this.request = http.request(this.options, resolve); | ||
} | ||
this.request.on('error', reject); | ||
if (this.options.body && isStream.readable(this.options.body)) { | ||
this.options.body.pipe(this.request); | ||
} | ||
else { | ||
this.request.end(this.options.body); | ||
} | ||
}); | ||
} | ||
_parse() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
this.body = yield concat(this.response); | ||
let json = this.headers['content-type'] === 'application/json'; | ||
if (json) | ||
this.body = JSON.parse(this.body); | ||
}); | ||
} | ||
_parseBody(body) { | ||
if (isStream.readable(body)) { | ||
this.options.body = body; | ||
return; | ||
} | ||
if (!this.options.headers['content-type']) { | ||
this.options.headers['content-type'] = 'application/json'; | ||
} | ||
if (this.options.headers['content-type'] === 'application/json') { | ||
this.options.body = JSON.stringify(body); | ||
} | ||
else { | ||
this.options.body = body; | ||
} | ||
this.options.headers['content-length'] = Buffer.byteLength(this.options.body).toString(); | ||
} | ||
_getNextRange() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const next = this.headers['next-range']; | ||
this.options.headers['range'] = Array.isArray(next) ? next[0] : next; | ||
let prev = this.body; | ||
yield this._request(); | ||
this.body = prev.concat(this.body); | ||
}); | ||
} | ||
_redactedHeaders(headers) { | ||
headers = Object.assign({}, headers); | ||
if (headers.authorization) | ||
headers.authorization = '[REDACTED]'; | ||
return headers; | ||
} | ||
get _responseOK() { | ||
if (!this.response) | ||
return false; | ||
return this.statusCode >= 200 && this.statusCode < 300; | ||
} | ||
get _responseRedirect() { | ||
if (!this.response) | ||
return false; | ||
return this.statusCode >= 300 && this.statusCode < 400; | ||
} | ||
get _shouldParseResponseBody() { | ||
return !this._responseOK || (!this.options.raw && this._responseOK); | ||
} | ||
_wait(ms) { | ||
return new Promise(resolve => setTimeout(resolve, ms)); | ||
} | ||
} | ||
exports.default = HTTP; | ||
exports.HTTP = HTTP; | ||
class HTTPError extends Error { | ||
constructor(http) { | ||
let message; | ||
if (typeof http.body === 'string' || typeof http.body.message === 'string') message = http.body.message || http.body;else message = _util2.default.inspect(http.body); | ||
super(`HTTP Error ${http.statusCode} for ${http.method} ${http.url}\n${message}`); | ||
this.__httpcall = true; | ||
this.statusCode = http.statusCode; | ||
this.http = http; | ||
this.body = http.body; | ||
} | ||
constructor(http) { | ||
super(); | ||
this.__httpcall = true; | ||
if (typeof http.body === 'string' || typeof http.body.message === 'string') | ||
this.message = http.body.message || http.body; | ||
else | ||
this.message = util.inspect(http.body); | ||
this.message = `HTTP Error ${http.statusCode} for ${http.method} ${http.url}\n${this.message}`; | ||
this.statusCode = http.statusCode; | ||
this.http = http; | ||
this.body = http.body; | ||
} | ||
} | ||
exports.HTTPError = HTTPError; // common/s helpers | ||
function get(url, options = {}) { | ||
return HTTP.get(url, options); | ||
} | ||
function post(url, options = {}) { | ||
return HTTP.post(url, options); | ||
} | ||
function put(url, options = {}) { | ||
return HTTP.put(url, options); | ||
} | ||
function patch(url, options = {}) { | ||
return HTTP.patch(url, options); | ||
} | ||
function hdelete(url, options = {}) { | ||
return HTTP.delete(url, options); | ||
} | ||
function stream(url, options = {}) { | ||
return HTTP.stream(url, options); | ||
} | ||
function request(url, options = {}) { | ||
return HTTP.request(url, options); | ||
} | ||
exports.HTTPError = HTTPError; |
134
lib/proxy.js
@@ -1,85 +0,61 @@ | ||
'use strict'; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
var _url = require('url'); | ||
var _url2 = _interopRequireDefault(_url); | ||
var _fs = require('fs'); | ||
var _fs2 = _interopRequireDefault(_fs); | ||
var _path = require('path'); | ||
var _path2 = _interopRequireDefault(_path); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const uri = require("url"); | ||
const fs = require("fs"); | ||
const path = require("path"); | ||
class ProxyUtil { | ||
static get httpProxy() { | ||
return this.env.HTTP_PROXY || this.env.http_proxy; | ||
} | ||
static get httpsProxy() { | ||
return this.env.HTTPS_PROXY || this.env.https_proxy; | ||
} | ||
static get usingProxy() { | ||
if (this.httpProxy || this.httpsProxy) return true; | ||
return false; | ||
} | ||
static get sslCertDir() { | ||
const certDir = this.env.SSL_CERT_DIR; | ||
if (certDir) { | ||
return _fs2.default.readdirSync(certDir).map(f => _path2.default.join(certDir, f)); | ||
} else { | ||
return []; | ||
static get httpProxy() { return this.env.HTTP_PROXY || this.env.http_proxy; } | ||
static get httpsProxy() { return this.env.HTTPS_PROXY || this.env.https_proxy; } | ||
static get usingProxy() { | ||
if (this.httpProxy || this.httpsProxy) | ||
return true; | ||
return false; | ||
} | ||
} | ||
static get sslCertFile() { | ||
return this.env.SSL_CERT_FILE ? [this.env.SSL_CERT_FILE] : []; | ||
} | ||
static get certs() { | ||
let filenames = this.sslCertFile.concat(this.sslCertDir); | ||
return filenames.map(function (filename) { | ||
return _fs2.default.readFileSync(filename); | ||
}); | ||
} | ||
static agent(https) { | ||
if (!this.usingProxy) return; | ||
const u = https ? this.httpsProxy || this.httpProxy : this.httpProxy; | ||
if (u) { | ||
let proxyParsed = _url2.default.parse(u); | ||
let tunnel = require('tunnel-agent'); | ||
let tunnelMethod = https ? tunnel.httpsOverHttp : tunnel.httpOverHttp; | ||
let opts = { | ||
proxy: { | ||
host: proxyParsed.hostname, | ||
port: proxyParsed.port || '8080' | ||
static get sslCertDir() { | ||
const certDir = this.env.SSL_CERT_DIR; | ||
if (certDir) { | ||
return fs.readdirSync(certDir).map(f => path.join(certDir, f)); | ||
} | ||
}; | ||
if (proxyParsed.auth) { | ||
opts.proxy.proxyAuth = proxyParsed.auth; | ||
} | ||
if (this.certs.length > 0) { | ||
opts.ca = this.certs; | ||
} | ||
let tunnelAgent = tunnelMethod(opts); | ||
if (https) { | ||
tunnelAgent.defaultPort = 443; | ||
} | ||
return tunnelAgent; | ||
else { | ||
return []; | ||
} | ||
} | ||
} | ||
static get sslCertFile() { | ||
return this.env.SSL_CERT_FILE ? [this.env.SSL_CERT_FILE] : []; | ||
} | ||
static get certs() { | ||
let filenames = this.sslCertFile.concat(this.sslCertDir); | ||
return filenames.map(function (filename) { | ||
return fs.readFileSync(filename); | ||
}); | ||
} | ||
static agent(https) { | ||
if (!this.usingProxy) | ||
return; | ||
const u = https ? (this.httpsProxy || this.httpProxy) : this.httpProxy; | ||
if (u) { | ||
let proxyParsed = uri.parse(u); | ||
let tunnel = require('tunnel-agent'); | ||
let tunnelMethod = https ? tunnel.httpsOverHttp : tunnel.httpOverHttp; | ||
let opts = { | ||
proxy: { | ||
host: proxyParsed.hostname, | ||
port: proxyParsed.port || '8080' | ||
} | ||
}; | ||
if (proxyParsed.auth) { | ||
opts.proxy.proxyAuth = proxyParsed.auth; | ||
} | ||
if (this.certs.length > 0) { | ||
opts.ca = this.certs; | ||
} | ||
let tunnelAgent = tunnelMethod(opts); | ||
if (https) { | ||
tunnelAgent.defaultPort = 443; | ||
} | ||
return tunnelAgent; | ||
} | ||
} | ||
} | ||
ProxyUtil.env = process.env; | ||
exports.default = ProxyUtil; | ||
ProxyUtil.env = process.env; |
{ | ||
"name": "http-call", | ||
"description": "make http requests", | ||
"version": "3.0.2", | ||
"author": "Jeff Dickey @dickeyxxx", | ||
"bugs": "https://github.com/dickeyxxx/http-call/issues", | ||
"version": "4.0.0-ts0", | ||
"author": "Jeff Dickey @jdxcode", | ||
"bugs": "https://github.com/jdxcode/http-call/issues", | ||
"dependencies": { | ||
@@ -14,27 +14,31 @@ "debug": "^3.0.1", | ||
"devDependencies": { | ||
"babel-cli": "^6.26.0", | ||
"babel-core": "^6.26.0", | ||
"babel-eslint": "7.2.3", | ||
"babel-jest": "^21.0.0", | ||
"babel-plugin-syntax-object-rest-spread": "^6.13.0", | ||
"babel-plugin-transform-class-properties": "6.24.1", | ||
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.0", | ||
"babel-plugin-transform-flow-strip-types": "6.22.0", | ||
"flow-bin": "^0.54.0", | ||
"flow-copy-source": "^1.2.1", | ||
"flow-typed": "^2.1.5", | ||
"@types/is-stream": "^1.1.0", | ||
"@types/jest": "^20.0.8", | ||
"@types/nock": "^8.2.1", | ||
"@types/node": "^8.0.28", | ||
"jest": "^21.0.1", | ||
"jsdoc-babel": "0.3.0", | ||
"jsdoc-to-markdown": "3.0.0", | ||
"nock": "^9.0.14", | ||
"remap-istanbul": "^0.9.5", | ||
"rimraf": "^2.6.1", | ||
"standard": "^10.0.3" | ||
"standard": "^10.0.3", | ||
"ts-jest": "^21.0.0", | ||
"typescript": "^2.5.2" | ||
}, | ||
"engines": { | ||
"node": ">=8.3.0" | ||
}, | ||
"files": [ | ||
"lib" | ||
], | ||
"homepage": "https://github.com/dickeyxxx/http-call", | ||
"homepage": "https://github.com/jdxcode/http-call", | ||
"jest": { | ||
"coverageReporters": [ | ||
"json" | ||
], | ||
"transform": { | ||
"^.+\\.ts$": "<rootDir>/node_modules/ts-jest/preprocessor.js" | ||
}, | ||
"testRegex": "\\.test\\.ts$", | ||
"moduleFileExtensions": [ | ||
"js", | ||
"ts" | ||
] | ||
}, | ||
"keywords": [ | ||
@@ -47,28 +51,10 @@ "http", | ||
"main": "lib/http.js", | ||
"repository": "dickeyxxx/http-call", | ||
"repository": "jdxcode/http-call", | ||
"scripts": { | ||
"build": "babel src -d lib --ignore '*.test.js'", | ||
"clean": "rimraf lib", | ||
"copy-flow": "flow-copy-source -v -i '*.test.js' src lib", | ||
"doc": "jsdoc2md -c doc/jsdoc2md.json --files src/http.js > README.md", | ||
"prepare": "npm run clean && npm run build && npm run copy-flow", | ||
"test": "jest && flow && standard", | ||
"watch": "nodemon -e js -i lib --exec \"npm run prepare\"" | ||
}, | ||
"standard": { | ||
"parser": "babel-eslint", | ||
"env": [ | ||
"jest" | ||
], | ||
"globals": [ | ||
"http$IncomingMessage", | ||
"http$ClientRequest", | ||
"$Diff", | ||
"$Shape", | ||
"Class" | ||
], | ||
"ignore": [ | ||
"flow-typed" | ||
] | ||
"coverage": "cat coverage/coverage-final.json | remap-istanbul -o coverage/coverage-final.json && curl -s https://codecov.io/bash | bash", | ||
"precommit": "lint-staged", | ||
"prepare": "rimraf lib && tsc && rimraf 'lib/**/*.test.js' 'lib/**/*.test.d.ts'", | ||
"pretest": "tsc --sourcemap", | ||
"test": "jest" | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 2 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 2 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
11
595
21581
2
3