Permalink
Cannot retrieve contributors at this time
618 lines (618 sloc)
26.8 KB
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
codeql-action/node_modules/@actions/http-client/lib/index.js
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
/* eslint-disable @typescript-eslint/no-explicit-any */ | |
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | |
if (k2 === undefined) k2 = k; | |
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | |
}) : (function(o, m, k, k2) { | |
if (k2 === undefined) k2 = k; | |
o[k2] = m[k]; | |
})); | |
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | |
Object.defineProperty(o, "default", { enumerable: true, value: v }); | |
}) : function(o, v) { | |
o["default"] = v; | |
}); | |
var __importStar = (this && this.__importStar) || function (mod) { | |
if (mod && mod.__esModule) return mod; | |
var result = {}; | |
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | |
__setModuleDefault(result, mod); | |
return result; | |
}; | |
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | |
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | |
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) : adopt(result.value).then(fulfilled, rejected); } | |
step((generator = generator.apply(thisArg, _arguments || [])).next()); | |
}); | |
}; | |
Object.defineProperty(exports, "__esModule", { value: true }); | |
exports.HttpClient = exports.isHttps = exports.HttpClientResponse = exports.HttpClientError = exports.getProxyUrl = exports.MediaTypes = exports.Headers = exports.HttpCodes = void 0; | |
const http = __importStar(require("http")); | |
const https = __importStar(require("https")); | |
const pm = __importStar(require("./proxy")); | |
const tunnel = __importStar(require("tunnel")); | |
var HttpCodes; | |
(function (HttpCodes) { | |
HttpCodes[HttpCodes["OK"] = 200] = "OK"; | |
HttpCodes[HttpCodes["MultipleChoices"] = 300] = "MultipleChoices"; | |
HttpCodes[HttpCodes["MovedPermanently"] = 301] = "MovedPermanently"; | |
HttpCodes[HttpCodes["ResourceMoved"] = 302] = "ResourceMoved"; | |
HttpCodes[HttpCodes["SeeOther"] = 303] = "SeeOther"; | |
HttpCodes[HttpCodes["NotModified"] = 304] = "NotModified"; | |
HttpCodes[HttpCodes["UseProxy"] = 305] = "UseProxy"; | |
HttpCodes[HttpCodes["SwitchProxy"] = 306] = "SwitchProxy"; | |
HttpCodes[HttpCodes["TemporaryRedirect"] = 307] = "TemporaryRedirect"; | |
HttpCodes[HttpCodes["PermanentRedirect"] = 308] = "PermanentRedirect"; | |
HttpCodes[HttpCodes["BadRequest"] = 400] = "BadRequest"; | |
HttpCodes[HttpCodes["Unauthorized"] = 401] = "Unauthorized"; | |
HttpCodes[HttpCodes["PaymentRequired"] = 402] = "PaymentRequired"; | |
HttpCodes[HttpCodes["Forbidden"] = 403] = "Forbidden"; | |
HttpCodes[HttpCodes["NotFound"] = 404] = "NotFound"; | |
HttpCodes[HttpCodes["MethodNotAllowed"] = 405] = "MethodNotAllowed"; | |
HttpCodes[HttpCodes["NotAcceptable"] = 406] = "NotAcceptable"; | |
HttpCodes[HttpCodes["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired"; | |
HttpCodes[HttpCodes["RequestTimeout"] = 408] = "RequestTimeout"; | |
HttpCodes[HttpCodes["Conflict"] = 409] = "Conflict"; | |
HttpCodes[HttpCodes["Gone"] = 410] = "Gone"; | |
HttpCodes[HttpCodes["TooManyRequests"] = 429] = "TooManyRequests"; | |
HttpCodes[HttpCodes["InternalServerError"] = 500] = "InternalServerError"; | |
HttpCodes[HttpCodes["NotImplemented"] = 501] = "NotImplemented"; | |
HttpCodes[HttpCodes["BadGateway"] = 502] = "BadGateway"; | |
HttpCodes[HttpCodes["ServiceUnavailable"] = 503] = "ServiceUnavailable"; | |
HttpCodes[HttpCodes["GatewayTimeout"] = 504] = "GatewayTimeout"; | |
})(HttpCodes = exports.HttpCodes || (exports.HttpCodes = {})); | |
var Headers; | |
(function (Headers) { | |
Headers["Accept"] = "accept"; | |
Headers["ContentType"] = "content-type"; | |
})(Headers = exports.Headers || (exports.Headers = {})); | |
var MediaTypes; | |
(function (MediaTypes) { | |
MediaTypes["ApplicationJson"] = "application/json"; | |
})(MediaTypes = exports.MediaTypes || (exports.MediaTypes = {})); | |
/** | |
* Returns the proxy URL, depending upon the supplied url and proxy environment variables. | |
* @param serverUrl The server URL where the request will be sent. For example, https://api.github.com | |
*/ | |
function getProxyUrl(serverUrl) { | |
const proxyUrl = pm.getProxyUrl(new URL(serverUrl)); | |
return proxyUrl ? proxyUrl.href : ''; | |
} | |
exports.getProxyUrl = getProxyUrl; | |
const HttpRedirectCodes = [ | |
HttpCodes.MovedPermanently, | |
HttpCodes.ResourceMoved, | |
HttpCodes.SeeOther, | |
HttpCodes.TemporaryRedirect, | |
HttpCodes.PermanentRedirect | |
]; | |
const HttpResponseRetryCodes = [ | |
HttpCodes.BadGateway, | |
HttpCodes.ServiceUnavailable, | |
HttpCodes.GatewayTimeout | |
]; | |
const RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD']; | |
const ExponentialBackoffCeiling = 10; | |
const ExponentialBackoffTimeSlice = 5; | |
class HttpClientError extends Error { | |
constructor(message, statusCode) { | |
super(message); | |
this.name = 'HttpClientError'; | |
this.statusCode = statusCode; | |
Object.setPrototypeOf(this, HttpClientError.prototype); | |
} | |
} | |
exports.HttpClientError = HttpClientError; | |
class HttpClientResponse { | |
constructor(message) { | |
this.message = message; | |
} | |
readBody() { | |
return __awaiter(this, void 0, void 0, function* () { | |
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { | |
let output = Buffer.alloc(0); | |
this.message.on('data', (chunk) => { | |
output = Buffer.concat([output, chunk]); | |
}); | |
this.message.on('end', () => { | |
resolve(output.toString()); | |
}); | |
})); | |
}); | |
} | |
readBodyBuffer() { | |
return __awaiter(this, void 0, void 0, function* () { | |
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { | |
const chunks = []; | |
this.message.on('data', (chunk) => { | |
chunks.push(chunk); | |
}); | |
this.message.on('end', () => { | |
resolve(Buffer.concat(chunks)); | |
}); | |
})); | |
}); | |
} | |
} | |
exports.HttpClientResponse = HttpClientResponse; | |
function isHttps(requestUrl) { | |
const parsedUrl = new URL(requestUrl); | |
return parsedUrl.protocol === 'https:'; | |
} | |
exports.isHttps = isHttps; | |
class HttpClient { | |
constructor(userAgent, handlers, requestOptions) { | |
this._ignoreSslError = false; | |
this._allowRedirects = true; | |
this._allowRedirectDowngrade = false; | |
this._maxRedirects = 50; | |
this._allowRetries = false; | |
this._maxRetries = 1; | |
this._keepAlive = false; | |
this._disposed = false; | |
this.userAgent = userAgent; | |
this.handlers = handlers || []; | |
this.requestOptions = requestOptions; | |
if (requestOptions) { | |
if (requestOptions.ignoreSslError != null) { | |
this._ignoreSslError = requestOptions.ignoreSslError; | |
} | |
this._socketTimeout = requestOptions.socketTimeout; | |
if (requestOptions.allowRedirects != null) { | |
this._allowRedirects = requestOptions.allowRedirects; | |
} | |
if (requestOptions.allowRedirectDowngrade != null) { | |
this._allowRedirectDowngrade = requestOptions.allowRedirectDowngrade; | |
} | |
if (requestOptions.maxRedirects != null) { | |
this._maxRedirects = Math.max(requestOptions.maxRedirects, 0); | |
} | |
if (requestOptions.keepAlive != null) { | |
this._keepAlive = requestOptions.keepAlive; | |
} | |
if (requestOptions.allowRetries != null) { | |
this._allowRetries = requestOptions.allowRetries; | |
} | |
if (requestOptions.maxRetries != null) { | |
this._maxRetries = requestOptions.maxRetries; | |
} | |
} | |
} | |
options(requestUrl, additionalHeaders) { | |
return __awaiter(this, void 0, void 0, function* () { | |
return this.request('OPTIONS', requestUrl, null, additionalHeaders || {}); | |
}); | |
} | |
get(requestUrl, additionalHeaders) { | |
return __awaiter(this, void 0, void 0, function* () { | |
return this.request('GET', requestUrl, null, additionalHeaders || {}); | |
}); | |
} | |
del(requestUrl, additionalHeaders) { | |
return __awaiter(this, void 0, void 0, function* () { | |
return this.request('DELETE', requestUrl, null, additionalHeaders || {}); | |
}); | |
} | |
post(requestUrl, data, additionalHeaders) { | |
return __awaiter(this, void 0, void 0, function* () { | |
return this.request('POST', requestUrl, data, additionalHeaders || {}); | |
}); | |
} | |
patch(requestUrl, data, additionalHeaders) { | |
return __awaiter(this, void 0, void 0, function* () { | |
return this.request('PATCH', requestUrl, data, additionalHeaders || {}); | |
}); | |
} | |
put(requestUrl, data, additionalHeaders) { | |
return __awaiter(this, void 0, void 0, function* () { | |
return this.request('PUT', requestUrl, data, additionalHeaders || {}); | |
}); | |
} | |
head(requestUrl, additionalHeaders) { | |
return __awaiter(this, void 0, void 0, function* () { | |
return this.request('HEAD', requestUrl, null, additionalHeaders || {}); | |
}); | |
} | |
sendStream(verb, requestUrl, stream, additionalHeaders) { | |
return __awaiter(this, void 0, void 0, function* () { | |
return this.request(verb, requestUrl, stream, additionalHeaders); | |
}); | |
} | |
/** | |
* Gets a typed object from an endpoint | |
* Be aware that not found returns a null. Other errors (4xx, 5xx) reject the promise | |
*/ | |
getJson(requestUrl, additionalHeaders = {}) { | |
return __awaiter(this, void 0, void 0, function* () { | |
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); | |
const res = yield this.get(requestUrl, additionalHeaders); | |
return this._processResponse(res, this.requestOptions); | |
}); | |
} | |
postJson(requestUrl, obj, additionalHeaders = {}) { | |
return __awaiter(this, void 0, void 0, function* () { | |
const data = JSON.stringify(obj, null, 2); | |
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); | |
additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); | |
const res = yield this.post(requestUrl, data, additionalHeaders); | |
return this._processResponse(res, this.requestOptions); | |
}); | |
} | |
putJson(requestUrl, obj, additionalHeaders = {}) { | |
return __awaiter(this, void 0, void 0, function* () { | |
const data = JSON.stringify(obj, null, 2); | |
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); | |
additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); | |
const res = yield this.put(requestUrl, data, additionalHeaders); | |
return this._processResponse(res, this.requestOptions); | |
}); | |
} | |
patchJson(requestUrl, obj, additionalHeaders = {}) { | |
return __awaiter(this, void 0, void 0, function* () { | |
const data = JSON.stringify(obj, null, 2); | |
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); | |
additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); | |
const res = yield this.patch(requestUrl, data, additionalHeaders); | |
return this._processResponse(res, this.requestOptions); | |
}); | |
} | |
/** | |
* Makes a raw http request. | |
* All other methods such as get, post, patch, and request ultimately call this. | |
* Prefer get, del, post and patch | |
*/ | |
request(verb, requestUrl, data, headers) { | |
return __awaiter(this, void 0, void 0, function* () { | |
if (this._disposed) { | |
throw new Error('Client has already been disposed.'); | |
} | |
const parsedUrl = new URL(requestUrl); | |
let info = this._prepareRequest(verb, parsedUrl, headers); | |
// Only perform retries on reads since writes may not be idempotent. | |
const maxTries = this._allowRetries && RetryableHttpVerbs.includes(verb) | |
? this._maxRetries + 1 | |
: 1; | |
let numTries = 0; | |
let response; | |
do { | |
response = yield this.requestRaw(info, data); | |
// Check if it's an authentication challenge | |
if (response && | |
response.message && | |
response.message.statusCode === HttpCodes.Unauthorized) { | |
let authenticationHandler; | |
for (const handler of this.handlers) { | |
if (handler.canHandleAuthentication(response)) { | |
authenticationHandler = handler; | |
break; | |
} | |
} | |
if (authenticationHandler) { | |
return authenticationHandler.handleAuthentication(this, info, data); | |
} | |
else { | |
// We have received an unauthorized response but have no handlers to handle it. | |
// Let the response return to the caller. | |
return response; | |
} | |
} | |
let redirectsRemaining = this._maxRedirects; | |
while (response.message.statusCode && | |
HttpRedirectCodes.includes(response.message.statusCode) && | |
this._allowRedirects && | |
redirectsRemaining > 0) { | |
const redirectUrl = response.message.headers['location']; | |
if (!redirectUrl) { | |
// if there's no location to redirect to, we won't | |
break; | |
} | |
const parsedRedirectUrl = new URL(redirectUrl); | |
if (parsedUrl.protocol === 'https:' && | |
parsedUrl.protocol !== parsedRedirectUrl.protocol && | |
!this._allowRedirectDowngrade) { | |
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.'); | |
} | |
// we need to finish reading the response before reassigning response | |
// which will leak the open socket. | |
yield response.readBody(); | |
// strip authorization header if redirected to a different hostname | |
if (parsedRedirectUrl.hostname !== parsedUrl.hostname) { | |
for (const header in headers) { | |
// header names are case insensitive | |
if (header.toLowerCase() === 'authorization') { | |
delete headers[header]; | |
} | |
} | |
} | |
// let's make the request with the new redirectUrl | |
info = this._prepareRequest(verb, parsedRedirectUrl, headers); | |
response = yield this.requestRaw(info, data); | |
redirectsRemaining--; | |
} | |
if (!response.message.statusCode || | |
!HttpResponseRetryCodes.includes(response.message.statusCode)) { | |
// If not a retry code, return immediately instead of retrying | |
return response; | |
} | |
numTries += 1; | |
if (numTries < maxTries) { | |
yield response.readBody(); | |
yield this._performExponentialBackoff(numTries); | |
} | |
} while (numTries < maxTries); | |
return response; | |
}); | |
} | |
/** | |
* Needs to be called if keepAlive is set to true in request options. | |
*/ | |
dispose() { | |
if (this._agent) { | |
this._agent.destroy(); | |
} | |
this._disposed = true; | |
} | |
/** | |
* Raw request. | |
* @param info | |
* @param data | |
*/ | |
requestRaw(info, data) { | |
return __awaiter(this, void 0, void 0, function* () { | |
return new Promise((resolve, reject) => { | |
function callbackForResult(err, res) { | |
if (err) { | |
reject(err); | |
} | |
else if (!res) { | |
// If `err` is not passed, then `res` must be passed. | |
reject(new Error('Unknown error')); | |
} | |
else { | |
resolve(res); | |
} | |
} | |
this.requestRawWithCallback(info, data, callbackForResult); | |
}); | |
}); | |
} | |
/** | |
* Raw request with callback. | |
* @param info | |
* @param data | |
* @param onResult | |
*/ | |
requestRawWithCallback(info, data, onResult) { | |
if (typeof data === 'string') { | |
if (!info.options.headers) { | |
info.options.headers = {}; | |
} | |
info.options.headers['Content-Length'] = Buffer.byteLength(data, 'utf8'); | |
} | |
let callbackCalled = false; | |
function handleResult(err, res) { | |
if (!callbackCalled) { | |
callbackCalled = true; | |
onResult(err, res); | |
} | |
} | |
const req = info.httpModule.request(info.options, (msg) => { | |
const res = new HttpClientResponse(msg); | |
handleResult(undefined, res); | |
}); | |
let socket; | |
req.on('socket', sock => { | |
socket = sock; | |
}); | |
// If we ever get disconnected, we want the socket to timeout eventually | |
req.setTimeout(this._socketTimeout || 3 * 60000, () => { | |
if (socket) { | |
socket.end(); | |
} | |
handleResult(new Error(`Request timeout: ${info.options.path}`)); | |
}); | |
req.on('error', function (err) { | |
// err has statusCode property | |
// res should have headers | |
handleResult(err); | |
}); | |
if (data && typeof data === 'string') { | |
req.write(data, 'utf8'); | |
} | |
if (data && typeof data !== 'string') { | |
data.on('close', function () { | |
req.end(); | |
}); | |
data.pipe(req); | |
} | |
else { | |
req.end(); | |
} | |
} | |
/** | |
* Gets an http agent. This function is useful when you need an http agent that handles | |
* routing through a proxy server - depending upon the url and proxy environment variables. | |
* @param serverUrl The server URL where the request will be sent. For example, https://api.github.com | |
*/ | |
getAgent(serverUrl) { | |
const parsedUrl = new URL(serverUrl); | |
return this._getAgent(parsedUrl); | |
} | |
_prepareRequest(method, requestUrl, headers) { | |
const info = {}; | |
info.parsedUrl = requestUrl; | |
const usingSsl = info.parsedUrl.protocol === 'https:'; | |
info.httpModule = usingSsl ? https : http; | |
const defaultPort = usingSsl ? 443 : 80; | |
info.options = {}; | |
info.options.host = info.parsedUrl.hostname; | |
info.options.port = info.parsedUrl.port | |
? parseInt(info.parsedUrl.port) | |
: defaultPort; | |
info.options.path = | |
(info.parsedUrl.pathname || '') + (info.parsedUrl.search || ''); | |
info.options.method = method; | |
info.options.headers = this._mergeHeaders(headers); | |
if (this.userAgent != null) { | |
info.options.headers['user-agent'] = this.userAgent; | |
} | |
info.options.agent = this._getAgent(info.parsedUrl); | |
// gives handlers an opportunity to participate | |
if (this.handlers) { | |
for (const handler of this.handlers) { | |
handler.prepareRequest(info.options); | |
} | |
} | |
return info; | |
} | |
_mergeHeaders(headers) { | |
if (this.requestOptions && this.requestOptions.headers) { | |
return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers || {})); | |
} | |
return lowercaseKeys(headers || {}); | |
} | |
_getExistingOrDefaultHeader(additionalHeaders, header, _default) { | |
let clientHeader; | |
if (this.requestOptions && this.requestOptions.headers) { | |
clientHeader = lowercaseKeys(this.requestOptions.headers)[header]; | |
} | |
return additionalHeaders[header] || clientHeader || _default; | |
} | |
_getAgent(parsedUrl) { | |
let agent; | |
const proxyUrl = pm.getProxyUrl(parsedUrl); | |
const useProxy = proxyUrl && proxyUrl.hostname; | |
if (this._keepAlive && useProxy) { | |
agent = this._proxyAgent; | |
} | |
if (this._keepAlive && !useProxy) { | |
agent = this._agent; | |
} | |
// if agent is already assigned use that agent. | |
if (agent) { | |
return agent; | |
} | |
const usingSsl = parsedUrl.protocol === 'https:'; | |
let maxSockets = 100; | |
if (this.requestOptions) { | |
maxSockets = this.requestOptions.maxSockets || http.globalAgent.maxSockets; | |
} | |
// This is `useProxy` again, but we need to check `proxyURl` directly for TypeScripts's flow analysis. | |
if (proxyUrl && proxyUrl.hostname) { | |
const agentOptions = { | |
maxSockets, | |
keepAlive: this._keepAlive, | |
proxy: Object.assign(Object.assign({}, ((proxyUrl.username || proxyUrl.password) && { | |
proxyAuth: `${proxyUrl.username}:${proxyUrl.password}` | |
})), { host: proxyUrl.hostname, port: proxyUrl.port }) | |
}; | |
let tunnelAgent; | |
const overHttps = proxyUrl.protocol === 'https:'; | |
if (usingSsl) { | |
tunnelAgent = overHttps ? tunnel.httpsOverHttps : tunnel.httpsOverHttp; | |
} | |
else { | |
tunnelAgent = overHttps ? tunnel.httpOverHttps : tunnel.httpOverHttp; | |
} | |
agent = tunnelAgent(agentOptions); | |
this._proxyAgent = agent; | |
} | |
// if reusing agent across request and tunneling agent isn't assigned create a new agent | |
if (this._keepAlive && !agent) { | |
const options = { keepAlive: this._keepAlive, maxSockets }; | |
agent = usingSsl ? new https.Agent(options) : new http.Agent(options); | |
this._agent = agent; | |
} | |
// if not using private agent and tunnel agent isn't setup then use global agent | |
if (!agent) { | |
agent = usingSsl ? https.globalAgent : http.globalAgent; | |
} | |
if (usingSsl && this._ignoreSslError) { | |
// we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process | |
// http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options | |
// we have to cast it to any and change it directly | |
agent.options = Object.assign(agent.options || {}, { | |
rejectUnauthorized: false | |
}); | |
} | |
return agent; | |
} | |
_performExponentialBackoff(retryNumber) { | |
return __awaiter(this, void 0, void 0, function* () { | |
retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber); | |
const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber); | |
return new Promise(resolve => setTimeout(() => resolve(), ms)); | |
}); | |
} | |
_processResponse(res, options) { | |
return __awaiter(this, void 0, void 0, function* () { | |
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { | |
const statusCode = res.message.statusCode || 0; | |
const response = { | |
statusCode, | |
result: null, | |
headers: {} | |
}; | |
// not found leads to null obj returned | |
if (statusCode === HttpCodes.NotFound) { | |
resolve(response); | |
} | |
// get the result from the body | |
function dateTimeDeserializer(key, value) { | |
if (typeof value === 'string') { | |
const a = new Date(value); | |
if (!isNaN(a.valueOf())) { | |
return a; | |
} | |
} | |
return value; | |
} | |
let obj; | |
let contents; | |
try { | |
contents = yield res.readBody(); | |
if (contents && contents.length > 0) { | |
if (options && options.deserializeDates) { | |
obj = JSON.parse(contents, dateTimeDeserializer); | |
} | |
else { | |
obj = JSON.parse(contents); | |
} | |
response.result = obj; | |
} | |
response.headers = res.message.headers; | |
} | |
catch (err) { | |
// Invalid resource (contents not json); leaving result obj null | |
} | |
// note that 3xx redirects are handled by the http layer. | |
if (statusCode > 299) { | |
let msg; | |
// if exception/error in body, attempt to get better error | |
if (obj && obj.message) { | |
msg = obj.message; | |
} | |
else if (contents && contents.length > 0) { | |
// it may be the case that the exception is in the body message as string | |
msg = contents; | |
} | |
else { | |
msg = `Failed request: (${statusCode})`; | |
} | |
const err = new HttpClientError(msg, statusCode); | |
err.result = response.result; | |
reject(err); | |
} | |
else { | |
resolve(response); | |
} | |
})); | |
}); | |
} | |
} | |
exports.HttpClient = HttpClient; | |
const lowercaseKeys = (obj) => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {}); | |
//# sourceMappingURL=index.js.map |