UNPKG

22.2 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.httpReq = httpReq;
7exports.httpReq2 = httpReq2;
8
9var _request = _interopRequireDefault(require("request"));
10
11var _lodash = _interopRequireDefault(require("lodash"));
12
13var _asyncUtils = require("./asyncUtils");
14
15var _errorUtils = require("./errorUtils");
16
17function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
18
19const promisifiedRequest = async options => await new Promise((resp, rej) => (0, _request.default)(options, (err, data) => err ? rej(err) : resp(data)));
20
21const DEFAULT_REQ_HEADERS = {};
22const DEFAULT_REQ_REJECT_UNAUTHORIZED = true;
23
24async function httpReq(url, options = {}) {
25 let body = null;
26
27 try {
28 options = options || {};
29 options.url = url;
30 options.method = options.method ? options.method.toUpperCase() : 'GET';
31 options.timeout = typeof options.timeout !== 'undefined' ? options.timeout : 5000;
32 options.headers = options.headers || DEFAULT_REQ_HEADERS;
33 options.body = typeof options.body === 'string' ? options.body : JSON.stringify(options.body);
34 options.rejectUnauthorized = typeof options.rejectUnauthorized !== 'undefined' ? options.rejectUnauthorized : DEFAULT_REQ_REJECT_UNAUTHORIZED;
35 options.maxRetries = options.maxRetries || 0;
36 options.expoBackoffMs = options.expoBackoffMs || 100;
37 return await (0, _asyncUtils.asyncRetry)(async triesExecuted => {
38 body = null;
39 const resp = await promisifiedRequest(options);
40
41 if (options.parseJsonResponse === true) {
42 try {
43 body = resp.body;
44 resp.bodyObj = JSON.parse(resp.body);
45 resp.triesExecuted = triesExecuted;
46 } catch (err) {
47 // NOTE: don't change this string without searching the code for it
48 throw new _errorUtils.ExtendedError('Failed to parse HTTP response as JSON', {
49 url: url,
50 bodyStart: resp.body.substr(0, 1000)
51 });
52 }
53 }
54
55 return resp;
56 }, {
57 opName: `${options.url}`,
58 maxRetries: options.maxRetries,
59 expoBackoffMs: options.expoBackoffMs,
60 asyncErrorHandler: options.asyncErrorHandler
61 });
62 } catch (err) {
63 throw new _errorUtils.ExtendedError('HTTP request failed', {
64 url,
65 err,
66 body
67 });
68 }
69}
70
71async function httpReq2(url, options = {}) {
72 let body = null;
73
74 try {
75 options = options || {};
76 options.url = url;
77 options.method = options.method ? options.method.toUpperCase() : 'GET';
78 options.timeout = typeof options.timeout !== 'undefined' ? options.timeout : 5000;
79 options.headers = options.headers || DEFAULT_REQ_HEADERS;
80 options.body = typeof options.body === 'string' ? options.body : JSON.stringify(options.body);
81 options.rejectUnauthorized = typeof options.rejectUnauthorized !== 'undefined' ? options.rejectUnauthorized : DEFAULT_REQ_REJECT_UNAUTHORIZED;
82 options.resultHandlers = options.resultHandlers ? _lodash.default.clone(options.resultHandlers) : options.resultHandlers;
83 let triesLeft = 1;
84 let triesExecuted = 0;
85 let resp = null;
86 let error = null;
87
88 while (triesLeft > 0) {
89 try {
90 triesExecuted++;
91 triesLeft--;
92 resp = await promisifiedRequest(options);
93 } catch (err) {
94 error = err;
95 }
96
97 if (options.resultHandlers) {
98 for (const resultHandler of options.resultHandlers) {
99 if (resultHandler.onStatus == null && resultHandler.onError == null || resp && typeof resultHandler.onStatus === 'number' && resultHandler.onStatus === resp.statusCode || resp && resultHandler.onStatus && typeof resultHandler.onStatus.test === 'function' && // $FlowIgnore
100 resultHandler.onStatus.test(resp.statusCode.toString()) || error && resultHandler.onError && typeof resultHandler.onError.test === 'function' && resultHandler.onError.test(error.message)) {
101 if (resultHandler.retry != null) {
102 if (resultHandler.retry > 0) {
103 triesLeft++;
104 resultHandler.retry--; // $FlowIgnore
105
106 resultHandler.nextBackoffMs = resultHandler.nextBackoffMs == null ? 100 : resultHandler.nextBackoffMs;
107 await (0, _asyncUtils.sleep)(resultHandler.nextBackoffMs); // $FlowIgnore
108
109 resultHandler.nextBackoffMs *= 1.5;
110 error = undefined;
111 resp = undefined;
112 }
113 } else if (resultHandler.throw != null) {
114 throw resultHandler.throw;
115 } else if (resultHandler.return != null) {
116 return resultHandler.return;
117 } else {
118 throw new _errorUtils.ExtendedError('Invalid result handler in httpReq', resultHandler);
119 }
120 }
121 }
122 }
123 }
124
125 if (resp) {
126 if (options.parseJsonResponse === true) {
127 try {
128 body = resp.body;
129 resp.bodyObj = JSON.parse(resp.body);
130 resp.triesExecuted = triesExecuted;
131 } catch (err) {
132 // NOTE: don't change this string without searching the code for it
133 throw new _errorUtils.ExtendedError('Failed to parse HTTP response as JSON', {
134 url: url,
135 bodyStart: resp.body.substr(0, 1000)
136 });
137 }
138 }
139
140 return resp;
141 }
142
143 throw error;
144 } catch (err) {
145 throw new _errorUtils.ExtendedError('HTTP request failed', {
146 url,
147 err,
148 body
149 });
150 }
151}
152//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy91bmluc3RydW1lbnRlZEh0dHBVdGlscy5qcyJdLCJuYW1lcyI6WyJwcm9taXNpZmllZFJlcXVlc3QiLCJvcHRpb25zIiwiUHJvbWlzZSIsInJlc3AiLCJyZWoiLCJlcnIiLCJkYXRhIiwiREVGQVVMVF9SRVFfSEVBREVSUyIsIkRFRkFVTFRfUkVRX1JFSkVDVF9VTkFVVEhPUklaRUQiLCJodHRwUmVxIiwidXJsIiwiYm9keSIsIm1ldGhvZCIsInRvVXBwZXJDYXNlIiwidGltZW91dCIsImhlYWRlcnMiLCJKU09OIiwic3RyaW5naWZ5IiwicmVqZWN0VW5hdXRob3JpemVkIiwibWF4UmV0cmllcyIsImV4cG9CYWNrb2ZmTXMiLCJ0cmllc0V4ZWN1dGVkIiwicGFyc2VKc29uUmVzcG9uc2UiLCJib2R5T2JqIiwicGFyc2UiLCJFeHRlbmRlZEVycm9yIiwiYm9keVN0YXJ0Iiwic3Vic3RyIiwib3BOYW1lIiwiYXN5bmNFcnJvckhhbmRsZXIiLCJodHRwUmVxMiIsInJlc3VsdEhhbmRsZXJzIiwiXyIsImNsb25lIiwidHJpZXNMZWZ0IiwiZXJyb3IiLCJyZXN1bHRIYW5kbGVyIiwib25TdGF0dXMiLCJvbkVycm9yIiwic3RhdHVzQ29kZSIsInRlc3QiLCJ0b1N0cmluZyIsIm1lc3NhZ2UiLCJyZXRyeSIsIm5leHRCYWNrb2ZmTXMiLCJ1bmRlZmluZWQiLCJ0aHJvdyIsInJldHVybiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFFQTs7QUFDQTs7QUFFQTs7QUFDQTs7OztBQUVBLE1BQU1BLGtCQUFrQixHQUFHLE1BQU9DLE9BQVAsSUFBMkIsTUFBTSxJQUFJQyxPQUFKLENBQVksQ0FBQ0MsSUFBRCxFQUFPQyxHQUFQLEtBQWUsc0JBQVFILE9BQVIsRUFBaUIsQ0FBQ0ksR0FBRCxFQUFNQyxJQUFOLEtBQWVELEdBQUcsR0FBR0QsR0FBRyxDQUFDQyxHQUFELENBQU4sR0FBY0YsSUFBSSxDQUFDRyxJQUFELENBQXJELENBQTNCLENBQTVEOztBQUVBLE1B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QUFPaEIsR0FBUCxFQUFZO0FBQ1o7QUFDQSxnQkFBTSxJQUFJb0IseUJBQUosQ0FBa0IsdUNBQWxCLEVBQTJEO0FBQUVmLFlBQUFBLEdBQUcsRUFBRUEsR0FBUDtBQUFZZ0IsWUFBQUEsU0FBUyxFQUFFdkIsSUFBSSxDQUFDUSxJQUFMLENBQVVnQixNQUFWLENBQWlCLENBQWpCLEVBQW9CLElBQXBCO0FBQXZCLFdBQTNELENBQU47QUFDRDtBQUNGOztBQUNELGFBQU94QixJQUFQO0FBQ0Q7O0FBRUQsVUFBTWdDLEtBQU47QUFFRCxHQTFGRCxDQTBGRSxPQUFPOUIsR0FBUCxFQUFZO0FBQ1osVUFBTSxJQUFJb0IseUJBQUosQ0FBa0IscUJBQWxCLEVBQXlDO0FBQUVmLE1BQUFBLEdBQUY7QUFBT0wsTUFBQUEsR0FBUDtBQUFZTSxNQUFBQTtBQUFaLEtBQXpDLENBQU47QUFDRDtBQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcblxuaW1wb3J0IHJlcXVlc3QgZnJvbSAncmVxdWVzdCdcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCdcblxuaW1wb3J0IHsgYXN5bmNSZXRyeSwgc2xlZXAgfSBmcm9tICcuL2FzeW5jVXRpbHMnXG5pbXBvcnQgeyBFeHRlbmRlZEVycm9yIH0gZnJvbSAnLi9lcnJvclV0aWxzJ1xuXG5jb25zdCBwcm9taXNpZmllZFJlcXVlc3QgPSBhc3luYyAob3B0aW9uczogT2JqZWN0KSA9PiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzcCwgcmVqKSA9PiByZXF1ZXN0KG9wdGlvbnMsIChlcnIsIGRhdGEpID0+IGVyciA/IHJlaihlcnIpIDogcmVzcChkYXRhKSkpXG5cbmNvbnN0IERFRkFVTFRfUkVRX0hFQURFUlMgPSB7fVxuY29uc3QgREVGQVVMVF9SRVFfUkVKRUNUX1VOQVVUSE9SSVpFRCA9IHRydWVcblxuZXhwb3J0IHR5cGUgSHR0cFJlcVJlc3BvbnNlID0ge3xcbiAgYm9keU9iajogP09iamVjdCwgXG4gIGJvZHk6IHN0cmluZywgXG4gIHN0YXR1c0NvZGU6IG51bWJlciwgXG4gIHRyaWVzRXhlY3V0ZWQ6IG51bWJlcixcbnx9XG5cbmV4cG9ydCB0eXBlIEh0dHBSZXFPcHRpb25zID0ge1xuICB1cmw/OiA/c3RyaW5nLFxuICBtZXRob2Q/OiBzdHJpbmcsXG4gIHRpbWVvdXQ/OiA/bnVtYmVyLFxuICBoZWFkZXJzPzogeyBbaWQ6IHN0cmluZ106IHN0cmluZyB9LFxuICBib2R5PzogP3N0cmluZyB8IE9iamVjdCxcbiAgbWF4UmV0cmllcz86IG51bWJlcixcbiAgZXhwb0JhY2tvZmZNcz86ID9udW1iZXIsXG4gIGFzeW5jRXJyb3JIYW5kbGVyPzogPyhPYmplY3QpID0+IFByb21pc2U8dm9pZD4sXG4gIHJlamVjdFVuYXV0aG9yaXplZD86IGJvb2xlYW4sXG4gIHRyYWNraW5nTmFtZT86ID9zdHJpbmcsXG4gIHBhcnNlSnNvblJlc3BvbnNlPzogP2Jvb2xlYW4sXG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBodHRwUmVxKHVybDogc3RyaW5nLCBvcHRpb25zOiBIdHRwUmVxT3B0aW9ucyA9IHt9KTogUHJvbWlzZTxIdHRwUmVxUmVzcG9uc2U+IHtcbiAgbGV0IGJvZHk6ID9zdHJpbmcgPSBudWxsXG4gIHRyeSB7XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge31cbiAgICBvcHRpb25zLnVybCA9IHVybFxuICAgIG9wdGlvbnMubWV0aG9kID0gb3B0aW9ucy5tZXRob2QgPyBvcHRpb25zLm1ldGhvZC50b1VwcGVyQ2FzZSgpIDogJ0dFVCdcbiAgICBvcHRpb25zLnRpbWVvdXQgPSB0eXBlb2Ygb3B0aW9ucy50aW1lb3V0ICE9PSAndW5kZWZpbmVkJyA/IG9wdGlvbnMudGltZW91dCA6IDUwMDBcbiAgICBvcHRpb25zLmhlYWRlcnMgPSBvcHRpb25zLmhlYWRlcnMgfHwgREVGQVVMVF9SRVFfSEVBREVSU1xuICAgIG9wdGlvbnMuYm9keSA9IHR5cGVvZiBvcHRpb25zLmJvZHkgPT09ICdzdHJpbmcnID8gb3B0aW9ucy5ib2R5IDogSlNPTi5zdHJpbmdpZnkob3B0aW9ucy5ib2R5KVxuICAgIG9wdGlvbnMucmVqZWN0VW5hdXRob3JpemVkID0gdHlwZW9mIG9wdGlvbnMucmVqZWN0VW5hdXRob3JpemVkICE9PSAndW5kZWZpbmVkJyA/IG9wdGlvbnMucmVqZWN0VW5hdXRob3JpemVkIDogREVGQVVMVF9SRVFfUkVKRUNUX1VOQVVUSE9SSVpFRFxuXG4gICAgb3B0aW9ucy5tYXhSZXRyaWVzID0gb3B0aW9ucy5tYXhSZXRyaWVzIHx8IDBcbiAgICBvcHRpb25zLmV4cG9CYWNrb2ZmTXMgPSBvcHRpb25zLmV4cG9CYWNrb2ZmTXMgfHwgMTAwXG5cbiAgICByZXR1cm4gYXdhaXQgYXN5bmNSZXRyeShhc3luYyAodHJpZXNFeGVjdXRlZCkgPT4ge1xuICAgICAgYm9keSA9IG51bGxcbiAgICAgIGNvbnN0IHJlc3AgPSBhd2FpdCBwcm9taXNpZmllZFJlcXVlc3Qob3B0aW9ucylcbiAgICAgIGlmIChvcHRpb25zLnBhcnNlSnNvblJlc3BvbnNlID09PSB0cnVlKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYm9keSA9IHJlc3AuYm9keVxuICAgICAgICAgIHJlc3AuYm9keU9iaiA9IEpTT04ucGFyc2UocmVzcC5ib2R5KVxuICAgICAgICAgIHJlc3AudHJpZXNFeGVjdXRlZCA9IHRyaWVzRXhlY3V0ZWRcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgLy8gTk9URTogZG9uJ3QgY2hhbmdlIHRoaXMgc3RyaW5nIHdpdGhvdXQgc2VhcmNoaW5nIHRoZSBjb2RlIGZvciBpdFxuICAgICAgICAgIHRocm93IG5ldyBFeHRlbmRlZEVycm9yKCdGYWlsZWQgdG8gcGFyc2UgSFRUUCByZXNwb25zZSBhcyBKU09OJywgeyB1cmw6IHVybCwgYm9keVN0YXJ0OiByZXNwLmJvZHkuc3Vic3RyKDAsIDEwMDApIH0pXG4gICAgICAgIH0gXG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzcFxuICAgIH0sIHtcbiAgICAgIG9wTmFtZTogYCR7b3B0aW9ucy51cmx9YCxcbiAgICAgIG1heFJldHJpZXM6IG9wdGlvbnMubWF4UmV0cmllcyxcbiAgICAgIGV4cG9CYWNrb2ZmTXM6IG9wdGlvbnMuZXhwb0JhY2tvZmZNcyxcbiAgICAgIGFzeW5jRXJyb3JIYW5kbGVyOiBvcHRpb25zLmFzeW5jRXJyb3JIYW5kbGVyLFxuICAgIH0pXG4gIH0gY2F0Y2ggKGVycikge1xuICAgIHRocm93IG5ldyBFeHRlbmRlZEVycm9yKCdIVFRQIHJlcXVlc3QgZmFpbGVkJywgeyB1cmwsIGVyciwgYm9keSB9KVxuICB9XG59XG5cblxudHlwZSBSZXN1bHRIYW5kbGVyVHJpZ2dlciA9IHt8XG4gIG9uRXJyb3I6IFJlZ0V4cCxcbnx9IHwge3xcbiAgb25TdGF0dXM6IG51bWJlciB8IFJlZ0V4cCxcbnx9IHwge3x8fVxudHlwZSBSZXN1bHRIYW5kbGVyQWN0aW9uID0ge3xcbiAgcmV0cnk6IG51bWJlcixcbiAgbmV4dEJhY2tvZmZNcz86ID9udW1iZXIsXG58fSB8IHt8XG4gIHRocm93OiBFcnJvcixcbnx9IHwge3xcbiAgcmV0dXJuOiBIdHRwUmVxUmVzcG9uc2UsXG58fVxudHlwZSBSZXN1bHRIYW5kbGVyID0ge3xcbiAgLi4uUmVzdWx0SGFuZGxlclRyaWdnZXIsXG4gIC4uLlJlc3VsdEhhbmRsZXJBY3Rpb24sXG58fVxuXG5leHBvcnQgdHlwZSBIdHRwUmVxT3B0aW9uczIgPSB7XG4gIHVybD86ID9zdHJpbmcsXG4gIG1ldGhvZD86IHN0cmluZyxcbiAgdGltZW91dD86ID9udW1iZXIsXG4gIGhlYWRlcnM/OiB7IFtpZDogc3RyaW5nXTogc3RyaW5nIH0sXG4gIGJvZHk/OiA/c3RyaW5nIHwgT2JqZWN0LFxuICBtYXhSZXRyaWVzPzogbnVtYmVyLFxuICByZWplY3RVbmF1dGhvcml6ZWQ/OiBib29sZWFuLFxuICB0cmFja2luZ05hbWU/OiA/c3RyaW5nLFxuICBwYXJzZUpzb25SZXNwb25zZT86ID9ib29sZWFuLFxuICByZXN1bHRIYW5kbGVycz86ID9BcnJheTxSZXN1bHRIYW5kbGVyPlxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaHR0cFJlcTIodXJsOiBzdHJpbmcsIG9wdGlvbnM6IEh0dHBSZXFPcHRpb25zMiA9IHt9KTogUHJvbWlzZTxIdHRwUmVxUmVzcG9uc2U+IHtcbiAgbGV0IGJvZHk6ID9zdHJpbmcgPSBudWxsXG4gIHRyeSB7XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge31cbiAgICBvcHRpb25zLnVybCA9IHVybFxuICAgIG9wdGlvbnMubWV0aG9kID0gb3B0aW9ucy5tZXRob2QgPyBvcHRpb25zLm1ldGhvZC50b1VwcGVyQ2FzZSgpIDogJ0dFVCdcbiAgICBvcHRpb25zLnRpbWVvdXQgPSB0eXBlb2Ygb3B0aW9ucy50aW1lb3V0ICE9PSAndW5kZWZpbmVkJyA/IG9wdGlvbnMudGltZW91dCA6IDUwMDBcbiAgICBvcHRpb25zLmhlYWRlcnMgPSBvcHRpb25zLmhlYWRlcnMgfHwgREVGQVVMVF9SRVFfSEVBREVSU1xuICAgIG9wdGlvbnMuYm9keSA9IHR5cGVvZiBvcHRpb25zLmJvZHkgPT09ICdzdHJpbmcnID8gb3B0aW9ucy5ib2R5IDogSlNPTi5zdHJpbmdpZnkob3B0aW9ucy5ib2R5KVxuICAgIG9wdGlvbnMucmVqZWN0VW5hdXRob3JpemVkID0gdHlwZW9mIG9wdGlvbnMucmVqZWN0VW5hdXRob3JpemVkICE9PSAndW5kZWZpbmVkJyA/IG9wdGlvbnMucmVqZWN0VW5hdXRob3JpemVkIDogREVGQVVMVF9SRVFfUkVKRUNUX1VOQVVUSE9SSVpFRFxuICAgIG9wdGlvbnMucmVzdWx0SGFuZGxlcnMgPSBvcHRpb25zLnJlc3VsdEhhbmRsZXJzID8gXy5jbG9uZShvcHRpb25zLnJlc3VsdEhhbmRsZXJzKSA6IG9wdGlvbnMucmVzdWx0SGFuZGxlcnNcblxuICAgIGxldCB0cmllc0xlZnQgPSAxXG4gICAgbGV0IHRyaWVzRXhlY3V0ZWQgPSAwXG5cbiAgICBsZXQgcmVzcDogP0h0dHBSZXFSZXNwb25zZSA9IG51bGxcbiAgICBsZXQgZXJyb3I6ID9FcnJvciA9IG51bGxcblxuICAgIHdoaWxlICh0cmllc0xlZnQgPiAwKSB7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHRyaWVzRXhlY3V0ZWQrK1xuICAgICAgICB0cmllc0xlZnQtLVxuICAgICAgICByZXNwID0gYXdhaXQgcHJvbWlzaWZpZWRSZXF1ZXN0KG9wdGlvbnMpXG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgZXJyb3IgPSBlcnJcbiAgICAgIH1cbiAgICAgIFxuICAgICAgaWYgKG9wdGlvbnMucmVzdWx0SGFuZGxlcnMpIHtcbiAgICAgICAgZm9yIChjb25zdCByZXN1bHRIYW5kbGVyIG9mIG9wdGlvbnMucmVzdWx0SGFuZGxlcnMpIHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAoXG4gICAgICAgICAgICAgIHJlc3VsdEhhbmRsZXIub25TdGF0dXMgPT0gbnVsbCAmJiBcbiAgICAgICAgICAgICAgcmVzdWx0SGFuZGxlci5vbkVycm9yID09IG51bGxcbiAgICAgICAgICAgICkgfHwgKFxuICAgICAgICAgICAgICByZXNwICYmIFxuICAgICAgICAgICAgICB0eXBlb2YgcmVzdWx0SGFuZGxlci5vblN0YXR1cyA9PT0gJ251bWJlcicgJiZcbiAgICAgICAgICAgICAgcmVzdWx0SGFuZGxlci5vblN0YXR1cyA9PT0gcmVzcC5zdGF0dXNDb2RlXG4gICAgICAgICAgICApIHx8IChcbiAgICAgICAgICAgICAgcmVzcCAmJiBcbiAgICAgICAgICAgICAgcmVzdWx0SGFuZGxlci5vblN0YXR1cyAmJiBcbiAgICAgICAgICAgICAgdHlwZW9mIHJlc3VsdEhhbmRsZXIub25TdGF0dXMudGVzdCA9PT0gJ2Z1bmN0aW9uJyAmJiBcbiAgICAgICAgICAgICAgLy8gJEZsb3dJZ25vcmVcbiAgICAgICAgICAgICAgcmVzdWx0SGFuZGxlci5vblN0YXR1cy50ZXN0KHJlc3Auc3RhdHVzQ29kZS50b1N0cmluZygpKVxuICAgICAgICAgICAgKSB8fCAoXG4gICAgICAgICAgICAgIGVycm9yICYmIFxuICAgICAgICAgICAgICByZXN1bHRIYW5kbGVyLm9uRXJyb3IgJiYgXG4gICAgICAgICAgICAgIHR5cGVvZiByZXN1bHRIYW5kbGVyLm9uRXJyb3IudGVzdCA9PT0gJ2Z1bmN0aW9uJyAmJiBcbiAgICAgICAgICAgICAgcmVzdWx0SGFuZGxlci5vbkVycm9yLnRlc3QoZXJyb3IubWVzc2FnZSlcbiAgICAgICAgICAgIClcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIGlmIChyZXN1bHRIYW5kbGVyLnJldHJ5ICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgaWYgKHJlc3VsdEhhbmRsZXIucmV0cnkgPiAwKSB7XG4gICAgICAgICAgICAgICAgdHJpZXNMZWZ0KytcbiAgICAgICAgICAgICAgICByZXN1bHRIYW5kbGVyLnJldHJ5LS1cbiAgICAgICAgICAgICAgICAvLyAkRmxvd0lnbm9yZVxuICAgICAgICAgICAgICAgIHJlc3VsdEhhbmRsZXIubmV4dEJhY2tvZmZNcyA9IHJlc3VsdEhhbmRsZXIubmV4dEJhY2tvZmZNcyA9PSBudWxsID8gMTAwIDogcmVzdWx0SGFuZGxlci5uZXh0QmFja29mZk1zXG4gICAgICAgICAgICAgICAgYXdhaXQgc2xlZXAocmVzdWx0SGFuZGxlci5uZXh0QmFja29mZk1zKVxuICAgICAgICAgICAgICAgIC8vICRGbG93SWdub3JlXG4gICAgICAgICAgICAgICAgcmVzdWx0SGFuZGxlci5uZXh0QmFja29mZk1zICo9IDEuNVxuXG4gICAgICAgICAgICAgICAgZXJyb3IgPSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICByZXNwID0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAocmVzdWx0SGFuZGxlci50aHJvdyAhPSBudWxsKSB7XG4gICAgICAgICAgICAgIHRocm93IHJlc3VsdEhhbmRsZXIudGhyb3dcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocmVzdWx0SGFuZGxlci5yZXR1cm4gIT0gbnVsbCkge1xuICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0SGFuZGxlci5yZXR1cm5cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFeHRlbmRlZEVycm9yKCdJbnZhbGlkIHJlc3VsdCBoYW5kbGVyIGluIGh0dHBSZXEnLCByZXN1bHRIYW5kbGVyKVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChyZXNwKSB7XG4gICAgICBpZiAob3B0aW9ucy5wYXJzZUpzb25SZXNwb25zZSA9PT0gdHJ1ZSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGJvZHkgPSByZXNwLmJvZHlcbiAgICAgICAgICByZXNwLmJvZHlPYmogPSBKU09OLnBhcnNlKHJlc3AuYm9keSlcbiAgICAgICAgICByZXNwLnRyaWVzRXhlY3V0ZWQgPSB0cmllc0V4ZWN1dGVkXG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIC8vIE5PVEU6IGRvbid0IGNoYW5nZSB0aGlzIHN0cmluZyB3aXRob3V0IHNlYXJjaGluZyB0aGUgY29kZSBmb3IgaXRcbiAgICAgICAgICB0aHJvdyBuZXcgRXh0ZW5kZWRFcnJvcignRmFpbGVkIHRvIHBhcnNlIEhUVFAgcmVzcG9uc2UgYXMgSlNPTicsIHsgdXJsOiB1cmwsIGJvZHlTdGFydDogcmVzcC5ib2R5LnN1YnN0cigwLCAxMDAwKSB9KVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzcFxuICAgIH1cblxuICAgIHRocm93IGVycm9yXG5cbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgdGhyb3cgbmV3IEV4dGVuZGVkRXJyb3IoJ0hUVFAgcmVxdWVzdCBmYWlsZWQnLCB7IHVybCwgZXJyLCBib2R5IH0pXG4gIH1cbn0iXX0=
\No newline at end of file