github.com/nektos/act@v0.2.63/pkg/runner/testdata/actions/node12/node_modules/@actions/http-client/lib/index.js (about) 1 "use strict"; 2 /* eslint-disable @typescript-eslint/no-explicit-any */ 3 var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 4 if (k2 === undefined) k2 = k; 5 Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); 6 }) : (function(o, m, k, k2) { 7 if (k2 === undefined) k2 = k; 8 o[k2] = m[k]; 9 })); 10 var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 11 Object.defineProperty(o, "default", { enumerable: true, value: v }); 12 }) : function(o, v) { 13 o["default"] = v; 14 }); 15 var __importStar = (this && this.__importStar) || function (mod) { 16 if (mod && mod.__esModule) return mod; 17 var result = {}; 18 if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 19 __setModuleDefault(result, mod); 20 return result; 21 }; 22 var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 23 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 24 return new (P || (P = Promise))(function (resolve, reject) { 25 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 26 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 27 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } 28 step((generator = generator.apply(thisArg, _arguments || [])).next()); 29 }); 30 }; 31 Object.defineProperty(exports, "__esModule", { value: true }); 32 exports.HttpClient = exports.isHttps = exports.HttpClientResponse = exports.HttpClientError = exports.getProxyUrl = exports.MediaTypes = exports.Headers = exports.HttpCodes = void 0; 33 const http = __importStar(require("http")); 34 const https = __importStar(require("https")); 35 const pm = __importStar(require("./proxy")); 36 const tunnel = __importStar(require("tunnel")); 37 var HttpCodes; 38 (function (HttpCodes) { 39 HttpCodes[HttpCodes["OK"] = 200] = "OK"; 40 HttpCodes[HttpCodes["MultipleChoices"] = 300] = "MultipleChoices"; 41 HttpCodes[HttpCodes["MovedPermanently"] = 301] = "MovedPermanently"; 42 HttpCodes[HttpCodes["ResourceMoved"] = 302] = "ResourceMoved"; 43 HttpCodes[HttpCodes["SeeOther"] = 303] = "SeeOther"; 44 HttpCodes[HttpCodes["NotModified"] = 304] = "NotModified"; 45 HttpCodes[HttpCodes["UseProxy"] = 305] = "UseProxy"; 46 HttpCodes[HttpCodes["SwitchProxy"] = 306] = "SwitchProxy"; 47 HttpCodes[HttpCodes["TemporaryRedirect"] = 307] = "TemporaryRedirect"; 48 HttpCodes[HttpCodes["PermanentRedirect"] = 308] = "PermanentRedirect"; 49 HttpCodes[HttpCodes["BadRequest"] = 400] = "BadRequest"; 50 HttpCodes[HttpCodes["Unauthorized"] = 401] = "Unauthorized"; 51 HttpCodes[HttpCodes["PaymentRequired"] = 402] = "PaymentRequired"; 52 HttpCodes[HttpCodes["Forbidden"] = 403] = "Forbidden"; 53 HttpCodes[HttpCodes["NotFound"] = 404] = "NotFound"; 54 HttpCodes[HttpCodes["MethodNotAllowed"] = 405] = "MethodNotAllowed"; 55 HttpCodes[HttpCodes["NotAcceptable"] = 406] = "NotAcceptable"; 56 HttpCodes[HttpCodes["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired"; 57 HttpCodes[HttpCodes["RequestTimeout"] = 408] = "RequestTimeout"; 58 HttpCodes[HttpCodes["Conflict"] = 409] = "Conflict"; 59 HttpCodes[HttpCodes["Gone"] = 410] = "Gone"; 60 HttpCodes[HttpCodes["TooManyRequests"] = 429] = "TooManyRequests"; 61 HttpCodes[HttpCodes["InternalServerError"] = 500] = "InternalServerError"; 62 HttpCodes[HttpCodes["NotImplemented"] = 501] = "NotImplemented"; 63 HttpCodes[HttpCodes["BadGateway"] = 502] = "BadGateway"; 64 HttpCodes[HttpCodes["ServiceUnavailable"] = 503] = "ServiceUnavailable"; 65 HttpCodes[HttpCodes["GatewayTimeout"] = 504] = "GatewayTimeout"; 66 })(HttpCodes = exports.HttpCodes || (exports.HttpCodes = {})); 67 var Headers; 68 (function (Headers) { 69 Headers["Accept"] = "accept"; 70 Headers["ContentType"] = "content-type"; 71 })(Headers = exports.Headers || (exports.Headers = {})); 72 var MediaTypes; 73 (function (MediaTypes) { 74 MediaTypes["ApplicationJson"] = "application/json"; 75 })(MediaTypes = exports.MediaTypes || (exports.MediaTypes = {})); 76 /** 77 * Returns the proxy URL, depending upon the supplied url and proxy environment variables. 78 * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com 79 */ 80 function getProxyUrl(serverUrl) { 81 const proxyUrl = pm.getProxyUrl(new URL(serverUrl)); 82 return proxyUrl ? proxyUrl.href : ''; 83 } 84 exports.getProxyUrl = getProxyUrl; 85 const HttpRedirectCodes = [ 86 HttpCodes.MovedPermanently, 87 HttpCodes.ResourceMoved, 88 HttpCodes.SeeOther, 89 HttpCodes.TemporaryRedirect, 90 HttpCodes.PermanentRedirect 91 ]; 92 const HttpResponseRetryCodes = [ 93 HttpCodes.BadGateway, 94 HttpCodes.ServiceUnavailable, 95 HttpCodes.GatewayTimeout 96 ]; 97 const RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD']; 98 const ExponentialBackoffCeiling = 10; 99 const ExponentialBackoffTimeSlice = 5; 100 class HttpClientError extends Error { 101 constructor(message, statusCode) { 102 super(message); 103 this.name = 'HttpClientError'; 104 this.statusCode = statusCode; 105 Object.setPrototypeOf(this, HttpClientError.prototype); 106 } 107 } 108 exports.HttpClientError = HttpClientError; 109 class HttpClientResponse { 110 constructor(message) { 111 this.message = message; 112 } 113 readBody() { 114 return __awaiter(this, void 0, void 0, function* () { 115 return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { 116 let output = Buffer.alloc(0); 117 this.message.on('data', (chunk) => { 118 output = Buffer.concat([output, chunk]); 119 }); 120 this.message.on('end', () => { 121 resolve(output.toString()); 122 }); 123 })); 124 }); 125 } 126 readBodyBuffer() { 127 return __awaiter(this, void 0, void 0, function* () { 128 return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { 129 const chunks = []; 130 this.message.on('data', (chunk) => { 131 chunks.push(chunk); 132 }); 133 this.message.on('end', () => { 134 resolve(Buffer.concat(chunks)); 135 }); 136 })); 137 }); 138 } 139 } 140 exports.HttpClientResponse = HttpClientResponse; 141 function isHttps(requestUrl) { 142 const parsedUrl = new URL(requestUrl); 143 return parsedUrl.protocol === 'https:'; 144 } 145 exports.isHttps = isHttps; 146 class HttpClient { 147 constructor(userAgent, handlers, requestOptions) { 148 this._ignoreSslError = false; 149 this._allowRedirects = true; 150 this._allowRedirectDowngrade = false; 151 this._maxRedirects = 50; 152 this._allowRetries = false; 153 this._maxRetries = 1; 154 this._keepAlive = false; 155 this._disposed = false; 156 this.userAgent = userAgent; 157 this.handlers = handlers || []; 158 this.requestOptions = requestOptions; 159 if (requestOptions) { 160 if (requestOptions.ignoreSslError != null) { 161 this._ignoreSslError = requestOptions.ignoreSslError; 162 } 163 this._socketTimeout = requestOptions.socketTimeout; 164 if (requestOptions.allowRedirects != null) { 165 this._allowRedirects = requestOptions.allowRedirects; 166 } 167 if (requestOptions.allowRedirectDowngrade != null) { 168 this._allowRedirectDowngrade = requestOptions.allowRedirectDowngrade; 169 } 170 if (requestOptions.maxRedirects != null) { 171 this._maxRedirects = Math.max(requestOptions.maxRedirects, 0); 172 } 173 if (requestOptions.keepAlive != null) { 174 this._keepAlive = requestOptions.keepAlive; 175 } 176 if (requestOptions.allowRetries != null) { 177 this._allowRetries = requestOptions.allowRetries; 178 } 179 if (requestOptions.maxRetries != null) { 180 this._maxRetries = requestOptions.maxRetries; 181 } 182 } 183 } 184 options(requestUrl, additionalHeaders) { 185 return __awaiter(this, void 0, void 0, function* () { 186 return this.request('OPTIONS', requestUrl, null, additionalHeaders || {}); 187 }); 188 } 189 get(requestUrl, additionalHeaders) { 190 return __awaiter(this, void 0, void 0, function* () { 191 return this.request('GET', requestUrl, null, additionalHeaders || {}); 192 }); 193 } 194 del(requestUrl, additionalHeaders) { 195 return __awaiter(this, void 0, void 0, function* () { 196 return this.request('DELETE', requestUrl, null, additionalHeaders || {}); 197 }); 198 } 199 post(requestUrl, data, additionalHeaders) { 200 return __awaiter(this, void 0, void 0, function* () { 201 return this.request('POST', requestUrl, data, additionalHeaders || {}); 202 }); 203 } 204 patch(requestUrl, data, additionalHeaders) { 205 return __awaiter(this, void 0, void 0, function* () { 206 return this.request('PATCH', requestUrl, data, additionalHeaders || {}); 207 }); 208 } 209 put(requestUrl, data, additionalHeaders) { 210 return __awaiter(this, void 0, void 0, function* () { 211 return this.request('PUT', requestUrl, data, additionalHeaders || {}); 212 }); 213 } 214 head(requestUrl, additionalHeaders) { 215 return __awaiter(this, void 0, void 0, function* () { 216 return this.request('HEAD', requestUrl, null, additionalHeaders || {}); 217 }); 218 } 219 sendStream(verb, requestUrl, stream, additionalHeaders) { 220 return __awaiter(this, void 0, void 0, function* () { 221 return this.request(verb, requestUrl, stream, additionalHeaders); 222 }); 223 } 224 /** 225 * Gets a typed object from an endpoint 226 * Be aware that not found returns a null. Other errors (4xx, 5xx) reject the promise 227 */ 228 getJson(requestUrl, additionalHeaders = {}) { 229 return __awaiter(this, void 0, void 0, function* () { 230 additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); 231 const res = yield this.get(requestUrl, additionalHeaders); 232 return this._processResponse(res, this.requestOptions); 233 }); 234 } 235 postJson(requestUrl, obj, additionalHeaders = {}) { 236 return __awaiter(this, void 0, void 0, function* () { 237 const data = JSON.stringify(obj, null, 2); 238 additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); 239 additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); 240 const res = yield this.post(requestUrl, data, additionalHeaders); 241 return this._processResponse(res, this.requestOptions); 242 }); 243 } 244 putJson(requestUrl, obj, additionalHeaders = {}) { 245 return __awaiter(this, void 0, void 0, function* () { 246 const data = JSON.stringify(obj, null, 2); 247 additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); 248 additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); 249 const res = yield this.put(requestUrl, data, additionalHeaders); 250 return this._processResponse(res, this.requestOptions); 251 }); 252 } 253 patchJson(requestUrl, obj, additionalHeaders = {}) { 254 return __awaiter(this, void 0, void 0, function* () { 255 const data = JSON.stringify(obj, null, 2); 256 additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); 257 additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); 258 const res = yield this.patch(requestUrl, data, additionalHeaders); 259 return this._processResponse(res, this.requestOptions); 260 }); 261 } 262 /** 263 * Makes a raw http request. 264 * All other methods such as get, post, patch, and request ultimately call this. 265 * Prefer get, del, post and patch 266 */ 267 request(verb, requestUrl, data, headers) { 268 return __awaiter(this, void 0, void 0, function* () { 269 if (this._disposed) { 270 throw new Error('Client has already been disposed.'); 271 } 272 const parsedUrl = new URL(requestUrl); 273 let info = this._prepareRequest(verb, parsedUrl, headers); 274 // Only perform retries on reads since writes may not be idempotent. 275 const maxTries = this._allowRetries && RetryableHttpVerbs.includes(verb) 276 ? this._maxRetries + 1 277 : 1; 278 let numTries = 0; 279 let response; 280 do { 281 response = yield this.requestRaw(info, data); 282 // Check if it's an authentication challenge 283 if (response && 284 response.message && 285 response.message.statusCode === HttpCodes.Unauthorized) { 286 let authenticationHandler; 287 for (const handler of this.handlers) { 288 if (handler.canHandleAuthentication(response)) { 289 authenticationHandler = handler; 290 break; 291 } 292 } 293 if (authenticationHandler) { 294 return authenticationHandler.handleAuthentication(this, info, data); 295 } 296 else { 297 // We have received an unauthorized response but have no handlers to handle it. 298 // Let the response return to the caller. 299 return response; 300 } 301 } 302 let redirectsRemaining = this._maxRedirects; 303 while (response.message.statusCode && 304 HttpRedirectCodes.includes(response.message.statusCode) && 305 this._allowRedirects && 306 redirectsRemaining > 0) { 307 const redirectUrl = response.message.headers['location']; 308 if (!redirectUrl) { 309 // if there's no location to redirect to, we won't 310 break; 311 } 312 const parsedRedirectUrl = new URL(redirectUrl); 313 if (parsedUrl.protocol === 'https:' && 314 parsedUrl.protocol !== parsedRedirectUrl.protocol && 315 !this._allowRedirectDowngrade) { 316 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.'); 317 } 318 // we need to finish reading the response before reassigning response 319 // which will leak the open socket. 320 yield response.readBody(); 321 // strip authorization header if redirected to a different hostname 322 if (parsedRedirectUrl.hostname !== parsedUrl.hostname) { 323 for (const header in headers) { 324 // header names are case insensitive 325 if (header.toLowerCase() === 'authorization') { 326 delete headers[header]; 327 } 328 } 329 } 330 // let's make the request with the new redirectUrl 331 info = this._prepareRequest(verb, parsedRedirectUrl, headers); 332 response = yield this.requestRaw(info, data); 333 redirectsRemaining--; 334 } 335 if (!response.message.statusCode || 336 !HttpResponseRetryCodes.includes(response.message.statusCode)) { 337 // If not a retry code, return immediately instead of retrying 338 return response; 339 } 340 numTries += 1; 341 if (numTries < maxTries) { 342 yield response.readBody(); 343 yield this._performExponentialBackoff(numTries); 344 } 345 } while (numTries < maxTries); 346 return response; 347 }); 348 } 349 /** 350 * Needs to be called if keepAlive is set to true in request options. 351 */ 352 dispose() { 353 if (this._agent) { 354 this._agent.destroy(); 355 } 356 this._disposed = true; 357 } 358 /** 359 * Raw request. 360 * @param info 361 * @param data 362 */ 363 requestRaw(info, data) { 364 return __awaiter(this, void 0, void 0, function* () { 365 return new Promise((resolve, reject) => { 366 function callbackForResult(err, res) { 367 if (err) { 368 reject(err); 369 } 370 else if (!res) { 371 // If `err` is not passed, then `res` must be passed. 372 reject(new Error('Unknown error')); 373 } 374 else { 375 resolve(res); 376 } 377 } 378 this.requestRawWithCallback(info, data, callbackForResult); 379 }); 380 }); 381 } 382 /** 383 * Raw request with callback. 384 * @param info 385 * @param data 386 * @param onResult 387 */ 388 requestRawWithCallback(info, data, onResult) { 389 if (typeof data === 'string') { 390 if (!info.options.headers) { 391 info.options.headers = {}; 392 } 393 info.options.headers['Content-Length'] = Buffer.byteLength(data, 'utf8'); 394 } 395 let callbackCalled = false; 396 function handleResult(err, res) { 397 if (!callbackCalled) { 398 callbackCalled = true; 399 onResult(err, res); 400 } 401 } 402 const req = info.httpModule.request(info.options, (msg) => { 403 const res = new HttpClientResponse(msg); 404 handleResult(undefined, res); 405 }); 406 let socket; 407 req.on('socket', sock => { 408 socket = sock; 409 }); 410 // If we ever get disconnected, we want the socket to timeout eventually 411 req.setTimeout(this._socketTimeout || 3 * 60000, () => { 412 if (socket) { 413 socket.end(); 414 } 415 handleResult(new Error(`Request timeout: ${info.options.path}`)); 416 }); 417 req.on('error', function (err) { 418 // err has statusCode property 419 // res should have headers 420 handleResult(err); 421 }); 422 if (data && typeof data === 'string') { 423 req.write(data, 'utf8'); 424 } 425 if (data && typeof data !== 'string') { 426 data.on('close', function () { 427 req.end(); 428 }); 429 data.pipe(req); 430 } 431 else { 432 req.end(); 433 } 434 } 435 /** 436 * Gets an http agent. This function is useful when you need an http agent that handles 437 * routing through a proxy server - depending upon the url and proxy environment variables. 438 * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com 439 */ 440 getAgent(serverUrl) { 441 const parsedUrl = new URL(serverUrl); 442 return this._getAgent(parsedUrl); 443 } 444 _prepareRequest(method, requestUrl, headers) { 445 const info = {}; 446 info.parsedUrl = requestUrl; 447 const usingSsl = info.parsedUrl.protocol === 'https:'; 448 info.httpModule = usingSsl ? https : http; 449 const defaultPort = usingSsl ? 443 : 80; 450 info.options = {}; 451 info.options.host = info.parsedUrl.hostname; 452 info.options.port = info.parsedUrl.port 453 ? parseInt(info.parsedUrl.port) 454 : defaultPort; 455 info.options.path = 456 (info.parsedUrl.pathname || '') + (info.parsedUrl.search || ''); 457 info.options.method = method; 458 info.options.headers = this._mergeHeaders(headers); 459 if (this.userAgent != null) { 460 info.options.headers['user-agent'] = this.userAgent; 461 } 462 info.options.agent = this._getAgent(info.parsedUrl); 463 // gives handlers an opportunity to participate 464 if (this.handlers) { 465 for (const handler of this.handlers) { 466 handler.prepareRequest(info.options); 467 } 468 } 469 return info; 470 } 471 _mergeHeaders(headers) { 472 if (this.requestOptions && this.requestOptions.headers) { 473 return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers || {})); 474 } 475 return lowercaseKeys(headers || {}); 476 } 477 _getExistingOrDefaultHeader(additionalHeaders, header, _default) { 478 let clientHeader; 479 if (this.requestOptions && this.requestOptions.headers) { 480 clientHeader = lowercaseKeys(this.requestOptions.headers)[header]; 481 } 482 return additionalHeaders[header] || clientHeader || _default; 483 } 484 _getAgent(parsedUrl) { 485 let agent; 486 const proxyUrl = pm.getProxyUrl(parsedUrl); 487 const useProxy = proxyUrl && proxyUrl.hostname; 488 if (this._keepAlive && useProxy) { 489 agent = this._proxyAgent; 490 } 491 if (this._keepAlive && !useProxy) { 492 agent = this._agent; 493 } 494 // if agent is already assigned use that agent. 495 if (agent) { 496 return agent; 497 } 498 const usingSsl = parsedUrl.protocol === 'https:'; 499 let maxSockets = 100; 500 if (this.requestOptions) { 501 maxSockets = this.requestOptions.maxSockets || http.globalAgent.maxSockets; 502 } 503 // This is `useProxy` again, but we need to check `proxyURl` directly for TypeScripts's flow analysis. 504 if (proxyUrl && proxyUrl.hostname) { 505 const agentOptions = { 506 maxSockets, 507 keepAlive: this._keepAlive, 508 proxy: Object.assign(Object.assign({}, ((proxyUrl.username || proxyUrl.password) && { 509 proxyAuth: `${proxyUrl.username}:${proxyUrl.password}` 510 })), { host: proxyUrl.hostname, port: proxyUrl.port }) 511 }; 512 let tunnelAgent; 513 const overHttps = proxyUrl.protocol === 'https:'; 514 if (usingSsl) { 515 tunnelAgent = overHttps ? tunnel.httpsOverHttps : tunnel.httpsOverHttp; 516 } 517 else { 518 tunnelAgent = overHttps ? tunnel.httpOverHttps : tunnel.httpOverHttp; 519 } 520 agent = tunnelAgent(agentOptions); 521 this._proxyAgent = agent; 522 } 523 // if reusing agent across request and tunneling agent isn't assigned create a new agent 524 if (this._keepAlive && !agent) { 525 const options = { keepAlive: this._keepAlive, maxSockets }; 526 agent = usingSsl ? new https.Agent(options) : new http.Agent(options); 527 this._agent = agent; 528 } 529 // if not using private agent and tunnel agent isn't setup then use global agent 530 if (!agent) { 531 agent = usingSsl ? https.globalAgent : http.globalAgent; 532 } 533 if (usingSsl && this._ignoreSslError) { 534 // we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process 535 // http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options 536 // we have to cast it to any and change it directly 537 agent.options = Object.assign(agent.options || {}, { 538 rejectUnauthorized: false 539 }); 540 } 541 return agent; 542 } 543 _performExponentialBackoff(retryNumber) { 544 return __awaiter(this, void 0, void 0, function* () { 545 retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber); 546 const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber); 547 return new Promise(resolve => setTimeout(() => resolve(), ms)); 548 }); 549 } 550 _processResponse(res, options) { 551 return __awaiter(this, void 0, void 0, function* () { 552 return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { 553 const statusCode = res.message.statusCode || 0; 554 const response = { 555 statusCode, 556 result: null, 557 headers: {} 558 }; 559 // not found leads to null obj returned 560 if (statusCode === HttpCodes.NotFound) { 561 resolve(response); 562 } 563 // get the result from the body 564 function dateTimeDeserializer(key, value) { 565 if (typeof value === 'string') { 566 const a = new Date(value); 567 if (!isNaN(a.valueOf())) { 568 return a; 569 } 570 } 571 return value; 572 } 573 let obj; 574 let contents; 575 try { 576 contents = yield res.readBody(); 577 if (contents && contents.length > 0) { 578 if (options && options.deserializeDates) { 579 obj = JSON.parse(contents, dateTimeDeserializer); 580 } 581 else { 582 obj = JSON.parse(contents); 583 } 584 response.result = obj; 585 } 586 response.headers = res.message.headers; 587 } 588 catch (err) { 589 // Invalid resource (contents not json); leaving result obj null 590 } 591 // note that 3xx redirects are handled by the http layer. 592 if (statusCode > 299) { 593 let msg; 594 // if exception/error in body, attempt to get better error 595 if (obj && obj.message) { 596 msg = obj.message; 597 } 598 else if (contents && contents.length > 0) { 599 // it may be the case that the exception is in the body message as string 600 msg = contents; 601 } 602 else { 603 msg = `Failed request: (${statusCode})`; 604 } 605 const err = new HttpClientError(msg, statusCode); 606 err.result = response.result; 607 reject(err); 608 } 609 else { 610 resolve(response); 611 } 612 })); 613 }); 614 } 615 } 616 exports.HttpClient = HttpClient; 617 const lowercaseKeys = (obj) => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {}); 618 //# sourceMappingURL=index.js.map