@verdaccio/proxy 8.0.0-next-8.30 → 8.0.0-next-8.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/agent.d.ts +2 -2
- package/build/agent.js +45 -32
- package/build/agent.js.map +1 -1
- package/build/index.js +2 -2
- package/build/index.js.map +1 -1
- package/build/proxy-utils.js +4 -4
- package/build/proxy-utils.js.map +1 -1
- package/build/proxy.d.ts +6 -4
- package/build/proxy.js +498 -409
- package/build/proxy.js.map +1 -1
- package/build/uplink-util.d.ts +2 -2
- package/build/uplink-util.js +18 -13
- package/build/uplink-util.js.map +1 -1
- package/package.json +5 -5
package/build/proxy.js
CHANGED
|
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
Object.defineProperty(exports, "FetchOptions", {
|
|
7
7
|
enumerable: true,
|
|
8
|
-
get: function () {
|
|
8
|
+
get: function get() {
|
|
9
9
|
return _gotCjs.Options;
|
|
10
10
|
}
|
|
11
11
|
});
|
|
@@ -19,36 +19,50 @@ var _nodeUrl = require("node:url");
|
|
|
19
19
|
var _core = require("@verdaccio/core");
|
|
20
20
|
var _agent = _interopRequireDefault(require("./agent"));
|
|
21
21
|
var _proxyUtils = require("./proxy-utils");
|
|
22
|
-
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" !=
|
|
23
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t3 in e) "default" !== _t3 && {}.hasOwnProperty.call(e, _t3) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t3)) && (i.get || i.set) ? o(f, _t3, i) : f[_t3] = e[_t3]); return f; })(e, t); }
|
|
23
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
|
24
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
25
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
26
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
27
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
28
|
+
function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
|
|
29
|
+
function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
|
|
30
|
+
function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
|
|
31
|
+
function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
|
|
32
|
+
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
|
|
33
|
+
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
|
|
34
|
+
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
|
|
35
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
36
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
37
|
+
var debug = (0, _debug["default"])('verdaccio:proxy');
|
|
38
|
+
var encode = function encode(thing) {
|
|
26
39
|
return encodeURIComponent(thing).replace(/^%40/, '@');
|
|
27
40
|
};
|
|
28
|
-
|
|
29
|
-
|
|
41
|
+
var jsonContentType = _core.HEADERS.JSON;
|
|
42
|
+
var contentTypeAccept = "".concat(jsonContentType, ";");
|
|
30
43
|
|
|
31
44
|
/**
|
|
32
45
|
* Just a helper (`config[key] || default` doesn't work because of zeroes)
|
|
33
46
|
*/
|
|
34
|
-
|
|
35
|
-
return _lodash
|
|
47
|
+
var setConfig = function setConfig(config, key, def) {
|
|
48
|
+
return _lodash["default"].isNil(config[key]) === false ? config[key] : def;
|
|
36
49
|
};
|
|
37
50
|
|
|
38
51
|
// this type is need it by storage
|
|
39
|
-
|
|
40
52
|
/**
|
|
41
53
|
* Implements Storage interface
|
|
42
54
|
* (same for storage.js, local-storage.js, up-storage.js)
|
|
43
55
|
*/
|
|
44
|
-
|
|
56
|
+
var ProxyStorage = exports.ProxyStorage = /*#__PURE__*/function () {
|
|
45
57
|
// @ts-ignore
|
|
46
58
|
|
|
47
|
-
|
|
59
|
+
function ProxyStorage(uplinkName, config, mainConfig, logger, agent) {
|
|
60
|
+
var _mainConfig$user_agen, _this$config$max_fail, _this$max_fails;
|
|
61
|
+
_classCallCheck(this, ProxyStorage);
|
|
48
62
|
this.uplinkName = uplinkName;
|
|
49
63
|
this.config = config;
|
|
50
64
|
this.failed_requests = 0;
|
|
51
|
-
this.userAgent = mainConfig.user_agent
|
|
65
|
+
this.userAgent = (_mainConfig$user_agen = mainConfig.user_agent) !== null && _mainConfig$user_agen !== void 0 ? _mainConfig$user_agen : 'hidden';
|
|
52
66
|
this.ca = config.ca;
|
|
53
67
|
this.logger = logger;
|
|
54
68
|
this.server_id = mainConfig.server_id;
|
|
@@ -58,9 +72,9 @@ class ProxyStorage {
|
|
|
58
72
|
maxFreeSockets: 10
|
|
59
73
|
});
|
|
60
74
|
this.url = new _nodeUrl.URL(this.config.url);
|
|
61
|
-
|
|
75
|
+
var isHTTPS = this.url.protocol === 'https:';
|
|
62
76
|
this._setupProxy(this.url.hostname, config, mainConfig, isHTTPS);
|
|
63
|
-
this.agent = agent
|
|
77
|
+
this.agent = agent !== null && agent !== void 0 ? agent : this.getAgent();
|
|
64
78
|
this.config.url = this.config.url.replace(/\/$/, '');
|
|
65
79
|
if (this.config.timeout && Number(this.config.timeout) >= 1000) {
|
|
66
80
|
this.logger.warn(['Too big timeout value: ' + this.config.timeout, 'We changed time format to nginx-like one', '(see http://nginx.org/en/docs/syntax.html)', 'so please update your config accordingly'].join('\n'));
|
|
@@ -73,436 +87,511 @@ class ProxyStorage {
|
|
|
73
87
|
request: (0, _proxyUtils.parseInterval)(setConfig(this.config, 'timeout', '30s'))
|
|
74
88
|
};
|
|
75
89
|
debug('set timeout %s', this.timeout);
|
|
76
|
-
this.max_fails = Number(setConfig(this.config, 'max_fails', this.config.max_fails
|
|
90
|
+
this.max_fails = Number(setConfig(this.config, 'max_fails', (_this$config$max_fail = this.config.max_fails) !== null && _this$config$max_fail !== void 0 ? _this$config$max_fail : 2));
|
|
77
91
|
this.fail_timeout = (0, _proxyUtils.parseInterval)(setConfig(this.config, 'fail_timeout', '5m'));
|
|
78
92
|
this.strict_ssl = Boolean(setConfig(this.config, 'strict_ssl', true));
|
|
79
93
|
this.retry = {
|
|
80
|
-
limit: this.max_fails
|
|
94
|
+
limit: (_this$max_fails = this.max_fails) !== null && _this$max_fails !== void 0 ? _this$max_fails : 2
|
|
81
95
|
};
|
|
82
96
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const accept = _core.HEADERS.ACCEPT;
|
|
94
|
-
const acceptEncoding = _core.HEADERS.ACCEPT_ENCODING;
|
|
95
|
-
const userAgent = _core.HEADERS.USER_AGENT;
|
|
96
|
-
headers[accept] = headers[accept] || contentTypeAccept;
|
|
97
|
-
headers[acceptEncoding] = headers[acceptEncoding] || 'gzip';
|
|
98
|
-
// registry.npmjs.org will only return search result if user-agent include string 'npm'
|
|
99
|
-
headers[userAgent] = headers[userAgent] || `npm (${this.userAgent})`;
|
|
100
|
-
return this.setAuthNext(headers);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Validate configuration auth and assign Header authorization
|
|
105
|
-
* @param {Object} headers
|
|
106
|
-
* @return {Object}
|
|
107
|
-
* @private
|
|
108
|
-
*/
|
|
109
|
-
setAuthNext(headers) {
|
|
110
|
-
const {
|
|
111
|
-
auth
|
|
112
|
-
} = this.config;
|
|
113
|
-
if (typeof auth === 'undefined' || typeof headers[_core.HEADERS.AUTHORIZATION] === 'string') {
|
|
114
|
-
return headers;
|
|
97
|
+
return _createClass(ProxyStorage, [{
|
|
98
|
+
key: "getAgent",
|
|
99
|
+
value: function getAgent() {
|
|
100
|
+
if (!this.agent) {
|
|
101
|
+
// TODO: the config.ca (certificates) is not yet injected here
|
|
102
|
+
var agentInstance = new _agent["default"](this.config.url, this.proxy, this.agent_options);
|
|
103
|
+
return agentInstance.get();
|
|
104
|
+
} else {
|
|
105
|
+
return this.agent;
|
|
106
|
+
}
|
|
115
107
|
}
|
|
116
|
-
|
|
117
|
-
|
|
108
|
+
}, {
|
|
109
|
+
key: "getHeaders",
|
|
110
|
+
value: function getHeaders() {
|
|
111
|
+
var headers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
112
|
+
var accept = _core.HEADERS.ACCEPT;
|
|
113
|
+
var acceptEncoding = _core.HEADERS.ACCEPT_ENCODING;
|
|
114
|
+
var userAgent = _core.HEADERS.USER_AGENT;
|
|
115
|
+
headers[accept] = headers[accept] || contentTypeAccept;
|
|
116
|
+
headers[acceptEncoding] = headers[acceptEncoding] || 'gzip';
|
|
117
|
+
// registry.npmjs.org will only return search result if user-agent include string 'npm'
|
|
118
|
+
headers[userAgent] = headers[userAgent] || "npm (".concat(this.userAgent, ")");
|
|
119
|
+
return this.setAuthNext(headers);
|
|
118
120
|
}
|
|
119
121
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
122
|
+
/**
|
|
123
|
+
* Validate configuration auth and assign Header authorization
|
|
124
|
+
* @param {Object} headers
|
|
125
|
+
* @return {Object}
|
|
126
|
+
* @private
|
|
127
|
+
*/
|
|
128
|
+
}, {
|
|
129
|
+
key: "setAuthNext",
|
|
130
|
+
value: function setAuthNext(headers) {
|
|
131
|
+
var auth = this.config.auth;
|
|
132
|
+
if (typeof auth === 'undefined' || typeof headers[_core.HEADERS.AUTHORIZATION] === 'string') {
|
|
133
|
+
return headers;
|
|
134
|
+
}
|
|
135
|
+
if (_lodash["default"].isObject(auth) === false && _lodash["default"].isObject(auth.token) === false) {
|
|
136
|
+
this._throwErrorAuth('Auth invalid');
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// get NPM_TOKEN http://blog.npmjs.org/post/118393368555/deploying-with-npm-private-modules
|
|
140
|
+
// or get other variable export in env
|
|
141
|
+
// https://github.com/verdaccio/verdaccio/releases/tag/v2.5.0
|
|
142
|
+
var token;
|
|
143
|
+
var tokenConf = auth;
|
|
144
|
+
if (_lodash["default"].isNil(tokenConf.token) === false && _lodash["default"].isString(tokenConf.token)) {
|
|
145
|
+
debug('use token from config');
|
|
146
|
+
token = tokenConf.token;
|
|
147
|
+
} else if (_lodash["default"].isNil(tokenConf.token_env) === false) {
|
|
148
|
+
if (typeof tokenConf.token_env === 'string') {
|
|
149
|
+
debug('use token from env %o', tokenConf.token_env);
|
|
150
|
+
token = process.env[tokenConf.token_env];
|
|
151
|
+
} else if (typeof tokenConf.token_env === 'boolean' && tokenConf.token_env) {
|
|
152
|
+
debug('use token from env NPM_TOKEN');
|
|
153
|
+
token = process.env.NPM_TOKEN;
|
|
154
|
+
} else {
|
|
155
|
+
this.logger.error(_core.constants.ERROR_CODE.token_required);
|
|
156
|
+
this._throwErrorAuth(_core.constants.ERROR_CODE.token_required);
|
|
157
|
+
}
|
|
158
|
+
} else {
|
|
133
159
|
debug('use token from env NPM_TOKEN');
|
|
134
160
|
token = process.env.NPM_TOKEN;
|
|
135
|
-
}
|
|
136
|
-
|
|
161
|
+
}
|
|
162
|
+
if (typeof token === 'undefined') {
|
|
137
163
|
this._throwErrorAuth(_core.constants.ERROR_CODE.token_required);
|
|
138
164
|
}
|
|
139
|
-
} else {
|
|
140
|
-
debug('use token from env NPM_TOKEN');
|
|
141
|
-
token = process.env.NPM_TOKEN;
|
|
142
|
-
}
|
|
143
|
-
if (typeof token === 'undefined') {
|
|
144
|
-
this._throwErrorAuth(_core.constants.ERROR_CODE.token_required);
|
|
145
|
-
}
|
|
146
165
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
return headers;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* @param {string} message
|
|
156
|
-
* @throws {Error}
|
|
157
|
-
* @private
|
|
158
|
-
*/
|
|
159
|
-
_throwErrorAuth(message) {
|
|
160
|
-
this.logger.error(message);
|
|
161
|
-
throw new Error(message);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Assign Header authorization with type authentication
|
|
166
|
-
* @param {Object} headers
|
|
167
|
-
* @param {string} type
|
|
168
|
-
* @param {string} token
|
|
169
|
-
* @private
|
|
170
|
-
*/
|
|
171
|
-
_setHeaderAuthorization(headers, type, token) {
|
|
172
|
-
const _type = type.toLowerCase();
|
|
173
|
-
if (_type !== _core.TOKEN_BEARER.toLowerCase() && _type !== _core.TOKEN_BASIC.toLowerCase()) {
|
|
174
|
-
this._throwErrorAuth(`Auth type '${_type}' not allowed`);
|
|
175
|
-
}
|
|
176
|
-
headers[_core.HEADERS.AUTHORIZATION] = _core.authUtils.buildToken(type, token);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* It will add or override specified headers from config file.
|
|
181
|
-
*
|
|
182
|
-
* Eg:
|
|
183
|
-
*
|
|
184
|
-
* uplinks:
|
|
185
|
-
npmjs:
|
|
186
|
-
url: https://registry.npmjs.org/
|
|
187
|
-
headers:
|
|
188
|
-
Accept: "application/vnd.npm.install-v2+json; q=1.0"
|
|
189
|
-
verdaccio-staging:
|
|
190
|
-
url: https://mycompany.com/npm
|
|
191
|
-
headers:
|
|
192
|
-
Accept: "application/json"
|
|
193
|
-
authorization: "Basic YourBase64EncodedCredentials=="
|
|
194
|
-
* @param {Object} headers
|
|
195
|
-
* @private
|
|
196
|
-
*/
|
|
197
|
-
applyUplinkHeaders(headers) {
|
|
198
|
-
if (!this.config.headers) {
|
|
166
|
+
// define type Auth allow basic and bearer
|
|
167
|
+
var type = tokenConf.type || _core.TOKEN_BASIC;
|
|
168
|
+
debug('token type %o', type);
|
|
169
|
+
this._setHeaderAuthorization(headers, type, token);
|
|
199
170
|
return headers;
|
|
200
171
|
}
|
|
201
172
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
173
|
+
/**
|
|
174
|
+
* @param {string} message
|
|
175
|
+
* @throws {Error}
|
|
176
|
+
* @private
|
|
177
|
+
*/
|
|
178
|
+
}, {
|
|
179
|
+
key: "_throwErrorAuth",
|
|
180
|
+
value: function _throwErrorAuth(message) {
|
|
181
|
+
this.logger.error(message);
|
|
182
|
+
throw new Error(message);
|
|
206
183
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Assign Header authorization with type authentication
|
|
187
|
+
* @param {Object} headers
|
|
188
|
+
* @param {string} type
|
|
189
|
+
* @param {string} token
|
|
190
|
+
* @private
|
|
191
|
+
*/
|
|
192
|
+
}, {
|
|
193
|
+
key: "_setHeaderAuthorization",
|
|
194
|
+
value: function _setHeaderAuthorization(headers, type, token) {
|
|
195
|
+
var _type = type.toLowerCase();
|
|
196
|
+
if (_type !== _core.TOKEN_BEARER.toLowerCase() && _type !== _core.TOKEN_BASIC.toLowerCase()) {
|
|
197
|
+
this._throwErrorAuth("Auth type '".concat(_type, "' not allowed"));
|
|
198
|
+
}
|
|
199
|
+
headers[_core.HEADERS.AUTHORIZATION] = _core.authUtils.buildToken(type, token);
|
|
212
200
|
}
|
|
213
201
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
202
|
+
/**
|
|
203
|
+
* It will add or override specified headers from config file.
|
|
204
|
+
*
|
|
205
|
+
* Eg:
|
|
206
|
+
*
|
|
207
|
+
* uplinks:
|
|
208
|
+
npmjs:
|
|
209
|
+
url: https://registry.npmjs.org/
|
|
210
|
+
headers:
|
|
211
|
+
Accept: "application/vnd.npm.install-v2+json; q=1.0"
|
|
212
|
+
verdaccio-staging:
|
|
213
|
+
url: https://mycompany.com/npm
|
|
214
|
+
headers:
|
|
215
|
+
Accept: "application/json"
|
|
216
|
+
authorization: "Basic YourBase64EncodedCredentials=="
|
|
217
|
+
* @param {Object} headers
|
|
218
|
+
* @private
|
|
219
|
+
*/
|
|
220
|
+
}, {
|
|
221
|
+
key: "applyUplinkHeaders",
|
|
222
|
+
value: function applyUplinkHeaders(headers) {
|
|
223
|
+
if (!this.config.headers) {
|
|
224
|
+
return headers;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// add/override headers specified in the config
|
|
228
|
+
/* eslint guard-for-in: 0 */
|
|
229
|
+
for (var _key in this.config.headers) {
|
|
230
|
+
headers[_key] = this.config.headers[_key];
|
|
231
|
+
}
|
|
232
|
+
return headers;
|
|
223
233
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
agent: this.agent,
|
|
237
|
-
retry,
|
|
238
|
-
timeout: this.timeout,
|
|
239
|
-
hooks: {
|
|
240
|
-
afterResponse: [afterResponse => {
|
|
241
|
-
const code = afterResponse.statusCode;
|
|
242
|
-
debug('after response code is %s', code);
|
|
243
|
-
if (code >= _core.HTTP_STATUS.OK && code < _core.HTTP_STATUS.MULTIPLE_CHOICES) {
|
|
244
|
-
if (this.failed_requests >= this.max_fails) {
|
|
245
|
-
this.failed_requests = 0;
|
|
246
|
-
this.logger.warn({
|
|
247
|
-
host: this.url.host
|
|
248
|
-
}, 'host @{host} is now online');
|
|
234
|
+
}, {
|
|
235
|
+
key: "getRemoteMetadata",
|
|
236
|
+
value: function () {
|
|
237
|
+
var _getRemoteMetadata = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(name, options) {
|
|
238
|
+
var _this = this;
|
|
239
|
+
var headers, method, uri, response, responseLength, _options$retry, _response, retry, etag, data, message, code, error, _t;
|
|
240
|
+
return _regenerator().w(function (_context) {
|
|
241
|
+
while (1) switch (_context.p = _context.n) {
|
|
242
|
+
case 0:
|
|
243
|
+
if (!this._ifRequestFailure()) {
|
|
244
|
+
_context.n = 1;
|
|
245
|
+
break;
|
|
249
246
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
247
|
+
throw _core.errorUtils.getInternalError(_core.API_ERROR.UPLINK_OFFLINE);
|
|
248
|
+
case 1:
|
|
249
|
+
// FUTURE: allow mix headers that comes from the client
|
|
250
|
+
debug('getting metadata for package %s', name);
|
|
251
|
+
headers = this.getHeaders(options === null || options === void 0 ? void 0 : options.headers);
|
|
252
|
+
headers = this.addProxyHeaders(headers, options.remoteAddress);
|
|
253
|
+
headers = this.applyUplinkHeaders(headers);
|
|
254
|
+
// the following headers cannot be overwritten
|
|
255
|
+
if (_lodash["default"].isNil(options.etag) === false) {
|
|
256
|
+
headers[_core.HEADERS.NONE_MATCH] = options.etag;
|
|
257
|
+
headers[_core.HEADERS.ACCEPT] = contentTypeAccept;
|
|
258
|
+
}
|
|
259
|
+
method = options.method || 'GET';
|
|
260
|
+
uri = this.config.url + "/".concat(encode(name));
|
|
261
|
+
debug('set retry limit is %s', this.retry.limit);
|
|
262
|
+
responseLength = 0;
|
|
263
|
+
_context.p = 2;
|
|
264
|
+
retry = (_options$retry = options === null || options === void 0 ? void 0 : options.retry) !== null && _options$retry !== void 0 ? _options$retry : this.retry;
|
|
265
|
+
debug('retry initial count %s', retry);
|
|
266
|
+
_context.n = 3;
|
|
267
|
+
return (0, _gotCjs["default"])(uri, {
|
|
268
|
+
headers: headers,
|
|
269
|
+
responseType: 'json',
|
|
258
270
|
method: method,
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
271
|
+
agent: this.agent,
|
|
272
|
+
retry: retry,
|
|
273
|
+
timeout: this.timeout,
|
|
274
|
+
hooks: {
|
|
275
|
+
afterResponse: [function (afterResponse) {
|
|
276
|
+
var code = afterResponse.statusCode;
|
|
277
|
+
debug('after response code is %s', code);
|
|
278
|
+
if (code >= _core.HTTP_STATUS.OK && code < _core.HTTP_STATUS.MULTIPLE_CHOICES) {
|
|
279
|
+
if (_this.failed_requests >= _this.max_fails) {
|
|
280
|
+
_this.failed_requests = 0;
|
|
281
|
+
_this.logger.warn({
|
|
282
|
+
host: _this.url.host
|
|
283
|
+
}, 'host @{host} is now online');
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return afterResponse;
|
|
287
|
+
}],
|
|
288
|
+
beforeRetry: [function (error, count) {
|
|
289
|
+
debug('retry %s count: %s', uri, count);
|
|
290
|
+
_this.failed_requests = count !== null && count !== void 0 ? count : 0;
|
|
291
|
+
_this.logger.info({
|
|
292
|
+
request: {
|
|
293
|
+
method: method,
|
|
294
|
+
url: uri
|
|
295
|
+
},
|
|
296
|
+
error: error.message,
|
|
297
|
+
retryCount: _this.failed_requests
|
|
298
|
+
}, "retry @{retryCount} req: '@{request.method} @{request.url}'");
|
|
299
|
+
if (_this.failed_requests >= _this.max_fails) {
|
|
300
|
+
_this.logger.warn({
|
|
301
|
+
host: _this.url.host
|
|
302
|
+
}, 'host @{host} is now offline');
|
|
303
|
+
}
|
|
304
|
+
}]
|
|
305
|
+
}
|
|
306
|
+
}).on('request', function () {
|
|
307
|
+
_this.last_request_time = Date.now();
|
|
308
|
+
}).on('response', function (eventResponse) {
|
|
309
|
+
var message = "@{!status}, req: '@{request.method} @{request.url}' (streaming)";
|
|
310
|
+
_this.logger.http({
|
|
311
|
+
request: {
|
|
312
|
+
method: method,
|
|
313
|
+
url: uri
|
|
314
|
+
},
|
|
315
|
+
status: _lodash["default"].isNull(eventResponse) === false ? eventResponse.statusCode : 'ERR'
|
|
316
|
+
}, message);
|
|
317
|
+
}).on('downloadProgress', function (progress) {
|
|
318
|
+
if (progress.total) {
|
|
319
|
+
debug('responseLength %s', progress.total);
|
|
320
|
+
responseLength = progress.total;
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
case 3:
|
|
324
|
+
response = _context.v;
|
|
325
|
+
etag = response.headers.etag;
|
|
326
|
+
data = response.body; // not modified status (304) registry does not return any payload
|
|
327
|
+
// it is handled as an error
|
|
328
|
+
if (!(((_response = response) === null || _response === void 0 ? void 0 : _response.statusCode) === _core.HTTP_STATUS.NOT_MODIFIED)) {
|
|
329
|
+
_context.n = 4;
|
|
330
|
+
break;
|
|
331
|
+
}
|
|
332
|
+
throw _core.errorUtils.getCode(_core.HTTP_STATUS.NOT_MODIFIED, _core.API_ERROR.NOT_MODIFIED_NO_DATA);
|
|
333
|
+
case 4:
|
|
334
|
+
debug('uri %s success', uri);
|
|
335
|
+
message = "@{!status}, req: '@{request.method} @{request.url}'";
|
|
336
|
+
this.logger.http({
|
|
337
|
+
// if error is null/false change this to undefined so it wont log
|
|
338
|
+
request: {
|
|
339
|
+
method: method,
|
|
340
|
+
url: uri
|
|
341
|
+
},
|
|
342
|
+
status: response.statusCode,
|
|
343
|
+
bytes: {
|
|
344
|
+
"in": options !== null && options !== void 0 && options.json ? JSON.stringify(options === null || options === void 0 ? void 0 : options.json).length : 0,
|
|
345
|
+
out: responseLength || 0
|
|
346
|
+
}
|
|
347
|
+
}, message);
|
|
348
|
+
return _context.a(2, [data, etag]);
|
|
349
|
+
case 5:
|
|
350
|
+
_context.p = 5;
|
|
351
|
+
_t = _context.v;
|
|
352
|
+
debug('error %s on uri %s', _t.code, uri);
|
|
353
|
+
if (!(_t.code === 'ERR_NON_2XX_3XX_RESPONSE')) {
|
|
354
|
+
_context.n = 8;
|
|
355
|
+
break;
|
|
356
|
+
}
|
|
357
|
+
code = _t.response.statusCode;
|
|
358
|
+
debug('error code %s', code);
|
|
359
|
+
if (!(code === _core.HTTP_STATUS.NOT_FOUND)) {
|
|
360
|
+
_context.n = 6;
|
|
361
|
+
break;
|
|
362
|
+
}
|
|
363
|
+
throw _core.errorUtils.getNotFound(_core.API_ERROR.NOT_PACKAGE_UPLINK);
|
|
364
|
+
case 6:
|
|
365
|
+
if (code >= _core.HTTP_STATUS.OK && code < _core.HTTP_STATUS.MULTIPLE_CHOICES) {
|
|
366
|
+
_context.n = 7;
|
|
367
|
+
break;
|
|
368
|
+
}
|
|
369
|
+
error = _core.errorUtils.getInternalError("".concat(_core.API_ERROR.BAD_STATUS_CODE, ": ").concat(code)); // we need this code to identify outside which status code triggered the error
|
|
370
|
+
error.remoteStatus = code;
|
|
371
|
+
throw error;
|
|
372
|
+
case 7:
|
|
373
|
+
_context.n = 9;
|
|
374
|
+
break;
|
|
375
|
+
case 8:
|
|
376
|
+
if (!this._isRequestTimeout(_t)) {
|
|
377
|
+
_context.n = 9;
|
|
378
|
+
break;
|
|
379
|
+
}
|
|
380
|
+
debug('error code timeout');
|
|
381
|
+
throw _core.errorUtils.getServiceUnavailable(_core.API_ERROR.SERVER_TIME_OUT);
|
|
382
|
+
case 9:
|
|
383
|
+
throw _t;
|
|
384
|
+
case 10:
|
|
385
|
+
return _context.a(2);
|
|
386
|
+
}
|
|
387
|
+
}, _callee, this, [[2, 5]]);
|
|
388
|
+
}));
|
|
389
|
+
function getRemoteMetadata(_x, _x2) {
|
|
390
|
+
return _getRemoteMetadata.apply(this, arguments);
|
|
391
|
+
}
|
|
392
|
+
return getRemoteMetadata;
|
|
393
|
+
}() // FIXME: handle stream and retry
|
|
394
|
+
}, {
|
|
395
|
+
key: "fetchTarball",
|
|
396
|
+
value: function fetchTarball(url, overrideOptions) {
|
|
397
|
+
var _this$retry,
|
|
398
|
+
_this2 = this;
|
|
399
|
+
debug('fetching url for %s', url);
|
|
400
|
+
var options = _objectSpread(_objectSpread({}, this.config), overrideOptions);
|
|
401
|
+
var headers = this.getHeaders(options === null || options === void 0 ? void 0 : options.headers);
|
|
402
|
+
headers = this.addProxyHeaders(headers, options.remoteAddress);
|
|
403
|
+
headers = this.applyUplinkHeaders(headers);
|
|
404
|
+
// the following headers cannot be overwritten
|
|
405
|
+
if (_lodash["default"].isNil(options.etag) === false) {
|
|
406
|
+
headers[_core.HEADERS.NONE_MATCH] = options.etag;
|
|
407
|
+
headers[_core.HEADERS.ACCEPT] = contentTypeAccept;
|
|
408
|
+
}
|
|
409
|
+
var method = 'GET';
|
|
410
|
+
// const uri = this.config.url + `/${encode(name)}`;
|
|
411
|
+
debug('request uri for %s', url);
|
|
412
|
+
var readStream = _gotCjs["default"].stream(url, {
|
|
413
|
+
headers: headers,
|
|
414
|
+
method: method,
|
|
415
|
+
agent: this.agent,
|
|
416
|
+
// FIXME: this should be taken from construtor as priority
|
|
417
|
+
retry: (_this$retry = this.retry) !== null && _this$retry !== void 0 ? _this$retry : options === null || options === void 0 ? void 0 : options.retry,
|
|
418
|
+
timeout: this.timeout
|
|
419
|
+
}).on('request', function () {
|
|
420
|
+
_this2.last_request_time = Date.now();
|
|
287
421
|
});
|
|
288
|
-
|
|
289
|
-
|
|
422
|
+
return readStream;
|
|
423
|
+
}
|
|
290
424
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
425
|
+
/**
|
|
426
|
+
* Perform a stream search.
|
|
427
|
+
* @param {*} options request options
|
|
428
|
+
* @return {Stream}
|
|
429
|
+
*/
|
|
430
|
+
}, {
|
|
431
|
+
key: "search",
|
|
432
|
+
value: (function () {
|
|
433
|
+
var _search = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(_ref) {
|
|
434
|
+
var url, abort, retry, uri, response, res, total, streamSearch, streamResponse, _t2;
|
|
435
|
+
return _regenerator().w(function (_context2) {
|
|
436
|
+
while (1) switch (_context2.p = _context2.n) {
|
|
437
|
+
case 0:
|
|
438
|
+
url = _ref.url, abort = _ref.abort, retry = _ref.retry;
|
|
439
|
+
_context2.p = 1;
|
|
440
|
+
// Incoming URL is relative ie /-/v1/search...
|
|
441
|
+
uri = new _nodeUrl.URL(url, this.url).href;
|
|
442
|
+
this.logger.http({
|
|
443
|
+
uri: uri,
|
|
444
|
+
uplink: this.uplinkName
|
|
445
|
+
}, 'search request to uplink @{uplink} - @{uri}');
|
|
446
|
+
debug('searching on %o', uri);
|
|
447
|
+
response = (0, _gotCjs["default"])(uri, {
|
|
448
|
+
signal: abort ? abort.signal : {},
|
|
449
|
+
agent: this.agent,
|
|
450
|
+
timeout: this.timeout,
|
|
451
|
+
retry: retry !== null && retry !== void 0 ? retry : this.retry
|
|
452
|
+
});
|
|
453
|
+
_context2.n = 2;
|
|
454
|
+
return response.text();
|
|
455
|
+
case 2:
|
|
456
|
+
res = _context2.v;
|
|
457
|
+
total = JSON.parse(res).total;
|
|
458
|
+
debug('number of packages found: %o', total);
|
|
459
|
+
streamSearch = new _nodeStream.PassThrough({
|
|
460
|
+
objectMode: true
|
|
461
|
+
});
|
|
462
|
+
streamResponse = _nodeStream.Readable.from(res); // objects is one of the properties on the body, it ignores date and total
|
|
463
|
+
streamResponse.pipe(_JSONStream["default"].parse('objects')).pipe(streamSearch, {
|
|
464
|
+
end: true
|
|
465
|
+
});
|
|
466
|
+
return _context2.a(2, streamSearch);
|
|
467
|
+
case 3:
|
|
468
|
+
_context2.p = 3;
|
|
469
|
+
_t2 = _context2.v;
|
|
470
|
+
debug('search error %s', _t2);
|
|
471
|
+
if (!(_t2.response.statusCode === 409)) {
|
|
472
|
+
_context2.n = 4;
|
|
473
|
+
break;
|
|
474
|
+
}
|
|
475
|
+
throw _core.errorUtils.getInternalError("bad status code ".concat(_t2.response.statusCode, " from uplink"));
|
|
476
|
+
case 4:
|
|
477
|
+
this.logger.error({
|
|
478
|
+
errorMessage: _t2 === null || _t2 === void 0 ? void 0 : _t2.message,
|
|
479
|
+
name: this.uplinkName
|
|
480
|
+
}, 'proxy uplink @{name} search error: @{errorMessage}');
|
|
481
|
+
throw _t2;
|
|
482
|
+
case 5:
|
|
483
|
+
return _context2.a(2);
|
|
484
|
+
}
|
|
485
|
+
}, _callee2, this, [[1, 3]]);
|
|
486
|
+
}));
|
|
487
|
+
function search(_x3) {
|
|
488
|
+
return _search.apply(this, arguments);
|
|
295
489
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
out: responseLength || 0
|
|
308
|
-
}
|
|
309
|
-
}, message);
|
|
310
|
-
return [data, etag];
|
|
311
|
-
} catch (err) {
|
|
312
|
-
debug('error %s on uri %s', err.code, uri);
|
|
313
|
-
if (err.code === 'ERR_NON_2XX_3XX_RESPONSE') {
|
|
314
|
-
const code = err.response.statusCode;
|
|
315
|
-
debug('error code %s', code);
|
|
316
|
-
if (code === _core.HTTP_STATUS.NOT_FOUND) {
|
|
317
|
-
throw _core.errorUtils.getNotFound(_core.API_ERROR.NOT_PACKAGE_UPLINK);
|
|
318
|
-
}
|
|
319
|
-
if (!(code >= _core.HTTP_STATUS.OK && code < _core.HTTP_STATUS.MULTIPLE_CHOICES)) {
|
|
320
|
-
const error = _core.errorUtils.getInternalError(`${_core.API_ERROR.BAD_STATUS_CODE}: ${code}`);
|
|
321
|
-
// we need this code to identify outside which status code triggered the error
|
|
322
|
-
error.remoteStatus = code;
|
|
323
|
-
throw error;
|
|
324
|
-
}
|
|
325
|
-
} else if (this._isRequestTimeout(err)) {
|
|
326
|
-
debug('error code timeout');
|
|
327
|
-
throw _core.errorUtils.getServiceUnavailable(_core.API_ERROR.SERVER_TIME_OUT);
|
|
490
|
+
return search;
|
|
491
|
+
}())
|
|
492
|
+
}, {
|
|
493
|
+
key: "addProxyHeaders",
|
|
494
|
+
value: function addProxyHeaders(headers, remoteAddress) {
|
|
495
|
+
// Only submit X-Forwarded-For field if we don't have a proxy selected
|
|
496
|
+
// in the config file.
|
|
497
|
+
//
|
|
498
|
+
// Otherwise misconfigured proxy could return 407
|
|
499
|
+
if (!this.proxy) {
|
|
500
|
+
headers[_core.HEADERS.FORWARDED_FOR] = (headers['x-forwarded-for'] ? headers['x-forwarded-for'] + ', ' : '') + remoteAddress;
|
|
328
501
|
}
|
|
329
|
-
throw err;
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
502
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
...this.config,
|
|
338
|
-
...overrideOptions
|
|
339
|
-
};
|
|
340
|
-
let headers = this.getHeaders(options?.headers);
|
|
341
|
-
headers = this.addProxyHeaders(headers, options.remoteAddress);
|
|
342
|
-
headers = this.applyUplinkHeaders(headers);
|
|
343
|
-
// the following headers cannot be overwritten
|
|
344
|
-
if (_lodash.default.isNil(options.etag) === false) {
|
|
345
|
-
headers[_core.HEADERS.NONE_MATCH] = options.etag;
|
|
346
|
-
headers[_core.HEADERS.ACCEPT] = contentTypeAccept;
|
|
503
|
+
// always attach Via header to avoid loops, even if we're not proxying
|
|
504
|
+
headers['via'] = headers['via'] ? headers['via'] + ', ' : '';
|
|
505
|
+
headers['via'] += '1.1 ' + this.server_id + ' (Verdaccio)';
|
|
506
|
+
return headers;
|
|
347
507
|
}
|
|
348
|
-
const method = 'GET';
|
|
349
|
-
// const uri = this.config.url + `/${encode(name)}`;
|
|
350
|
-
debug('request uri for %s', url);
|
|
351
|
-
const readStream = _gotCjs.default.stream(url, {
|
|
352
|
-
headers,
|
|
353
|
-
method,
|
|
354
|
-
agent: this.agent,
|
|
355
|
-
// FIXME: this should be taken from construtor as priority
|
|
356
|
-
retry: this.retry ?? options?.retry,
|
|
357
|
-
timeout: this.timeout
|
|
358
|
-
}).on('request', () => {
|
|
359
|
-
this.last_request_time = Date.now();
|
|
360
|
-
});
|
|
361
|
-
return readStream;
|
|
362
|
-
}
|
|
363
508
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
}) {
|
|
374
|
-
try {
|
|
375
|
-
// Incoming URL is relative ie /-/v1/search...
|
|
376
|
-
const uri = new _nodeUrl.URL(url, this.url).href;
|
|
377
|
-
this.logger.http({
|
|
378
|
-
uri,
|
|
379
|
-
uplink: this.uplinkName
|
|
380
|
-
}, 'search request to uplink @{uplink} - @{uri}');
|
|
381
|
-
debug('searching on %o', uri);
|
|
382
|
-
const response = (0, _gotCjs.default)(uri, {
|
|
383
|
-
signal: abort ? abort.signal : {},
|
|
384
|
-
agent: this.agent,
|
|
385
|
-
timeout: this.timeout,
|
|
386
|
-
retry: retry ?? this.retry
|
|
387
|
-
});
|
|
388
|
-
const res = await response.text();
|
|
389
|
-
const total = JSON.parse(res).total;
|
|
390
|
-
debug('number of packages found: %o', total);
|
|
391
|
-
const streamSearch = new _nodeStream.PassThrough({
|
|
392
|
-
objectMode: true
|
|
393
|
-
});
|
|
394
|
-
const streamResponse = _nodeStream.Readable.from(res);
|
|
395
|
-
// objects is one of the properties on the body, it ignores date and total
|
|
396
|
-
streamResponse.pipe(_JSONStream.default.parse('objects')).pipe(streamSearch, {
|
|
397
|
-
end: true
|
|
398
|
-
});
|
|
399
|
-
return streamSearch;
|
|
400
|
-
} catch (err) {
|
|
401
|
-
debug('search error %s', err);
|
|
402
|
-
if (err.response.statusCode === 409) {
|
|
403
|
-
throw _core.errorUtils.getInternalError(`bad status code ${err.response.statusCode} from uplink`);
|
|
404
|
-
}
|
|
405
|
-
this.logger.error({
|
|
406
|
-
errorMessage: err?.message,
|
|
407
|
-
name: this.uplinkName
|
|
408
|
-
}, 'proxy uplink @{name} search error: @{errorMessage}');
|
|
409
|
-
throw err;
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
addProxyHeaders(headers, remoteAddress) {
|
|
413
|
-
// Only submit X-Forwarded-For field if we don't have a proxy selected
|
|
414
|
-
// in the config file.
|
|
415
|
-
//
|
|
416
|
-
// Otherwise misconfigured proxy could return 407
|
|
417
|
-
if (!this.proxy) {
|
|
418
|
-
headers[_core.HEADERS.FORWARDED_FOR] = (headers['x-forwarded-for'] ? headers['x-forwarded-for'] + ', ' : '') + remoteAddress;
|
|
509
|
+
/**
|
|
510
|
+
* If the request failure.
|
|
511
|
+
* @return {boolean}
|
|
512
|
+
* @private
|
|
513
|
+
*/
|
|
514
|
+
}, {
|
|
515
|
+
key: "_ifRequestFailure",
|
|
516
|
+
value: function _ifRequestFailure() {
|
|
517
|
+
return this.failed_requests >= this.max_fails && Math.abs(Date.now() - this.last_request_time) < this.fail_timeout;
|
|
419
518
|
}
|
|
420
519
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
return this.failed_requests >= this.max_fails && Math.abs(Date.now() - this.last_request_time) < this.fail_timeout;
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
/**
|
|
437
|
-
* Check if the request timed out (network or http errors).
|
|
438
|
-
* @param {RequestError} err
|
|
439
|
-
* @return {boolean}
|
|
440
|
-
*/
|
|
441
|
-
_isRequestTimeout(err) {
|
|
442
|
-
const code = err?.response?.statusCode;
|
|
443
|
-
return err.code === 'ETIMEDOUT' || err.code === 'ESOCKETTIMEDOUT' || err.code === 'ECONNRESET' || code === _core.HTTP_STATUS.REQUEST_TIMEOUT || code === _core.HTTP_STATUS.BAD_GATEWAY || code === _core.HTTP_STATUS.SERVICE_UNAVAILABLE || code === _core.HTTP_STATUS.GATEWAY_TIMEOUT;
|
|
444
|
-
}
|
|
520
|
+
/**
|
|
521
|
+
* Check if the request timed out (network or http errors).
|
|
522
|
+
* @param {RequestError} err
|
|
523
|
+
* @return {boolean}
|
|
524
|
+
*/
|
|
525
|
+
}, {
|
|
526
|
+
key: "_isRequestTimeout",
|
|
527
|
+
value: function _isRequestTimeout(err) {
|
|
528
|
+
var _err$response;
|
|
529
|
+
var code = err === null || err === void 0 || (_err$response = err.response) === null || _err$response === void 0 ? void 0 : _err$response.statusCode;
|
|
530
|
+
return err.code === 'ETIMEDOUT' || err.code === 'ESOCKETTIMEDOUT' || err.code === 'ECONNRESET' || code === _core.HTTP_STATUS.REQUEST_TIMEOUT || code === _core.HTTP_STATUS.BAD_GATEWAY || code === _core.HTTP_STATUS.SERVICE_UNAVAILABLE || code === _core.HTTP_STATUS.GATEWAY_TIMEOUT;
|
|
531
|
+
}
|
|
445
532
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
533
|
+
/**
|
|
534
|
+
* Set up a proxy.
|
|
535
|
+
* @param {*} hostname
|
|
536
|
+
* @param {*} config
|
|
537
|
+
* @param {*} mainconfig
|
|
538
|
+
* @param {*} isHTTPS
|
|
539
|
+
*/
|
|
540
|
+
}, {
|
|
541
|
+
key: "_setupProxy",
|
|
542
|
+
value: function _setupProxy(hostname, config, mainconfig, isHTTPS) {
|
|
543
|
+
var noProxyList;
|
|
544
|
+
var proxy_key = isHTTPS ? 'https_proxy' : 'http_proxy';
|
|
545
|
+
debug('looking for %o', proxy_key);
|
|
457
546
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
547
|
+
// get http_proxy and no_proxy configs
|
|
548
|
+
if (proxy_key in config) {
|
|
549
|
+
this.proxy = config[proxy_key];
|
|
550
|
+
debug('found %o in uplink config', this.proxy);
|
|
551
|
+
} else if (proxy_key in mainconfig) {
|
|
552
|
+
this.proxy = mainconfig[proxy_key];
|
|
553
|
+
debug('found %o in main config', this.proxy);
|
|
554
|
+
}
|
|
555
|
+
if ('no_proxy' in config) {
|
|
556
|
+
noProxyList = config.no_proxy;
|
|
557
|
+
} else if ('no_proxy' in mainconfig) {
|
|
558
|
+
noProxyList = mainconfig.no_proxy;
|
|
559
|
+
}
|
|
471
560
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
561
|
+
// use wget-like algorithm to determine if proxy shouldn't be used
|
|
562
|
+
if (hostname[0] !== '.') {
|
|
563
|
+
hostname = '.' + hostname;
|
|
564
|
+
}
|
|
565
|
+
if (_lodash["default"].isString(noProxyList) && noProxyList.length) {
|
|
566
|
+
noProxyList = noProxyList.split(',');
|
|
567
|
+
}
|
|
568
|
+
if (_lodash["default"].isArray(noProxyList)) {
|
|
569
|
+
for (var i = 0; i < noProxyList.length; i++) {
|
|
570
|
+
var noProxyItem = noProxyList[i];
|
|
571
|
+
if (noProxyItem[0] !== '.') {
|
|
572
|
+
noProxyItem = '.' + noProxyItem;
|
|
573
|
+
}
|
|
574
|
+
if (hostname.endsWith(noProxyItem)) {
|
|
575
|
+
if (this.proxy) {
|
|
576
|
+
debug('not using proxy, excluded by @{rule}', noProxyItem);
|
|
577
|
+
this.logger.debug({
|
|
578
|
+
url: this.url.href,
|
|
579
|
+
rule: noProxyItem
|
|
580
|
+
}, 'not using proxy for @{url}, excluded by @{rule} rule');
|
|
581
|
+
this.proxy = undefined;
|
|
582
|
+
}
|
|
583
|
+
break;
|
|
493
584
|
}
|
|
494
|
-
break;
|
|
495
585
|
}
|
|
496
586
|
}
|
|
587
|
+
if (typeof this.proxy === 'string') {
|
|
588
|
+
debug('using proxy @{proxy} for @{url}', this.proxy, this.url.href);
|
|
589
|
+
this.logger.debug({
|
|
590
|
+
url: this.url.href,
|
|
591
|
+
proxy: this.proxy
|
|
592
|
+
}, 'using proxy @{proxy} for @{url}');
|
|
593
|
+
}
|
|
497
594
|
}
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
this.logger.debug({
|
|
501
|
-
url: this.url.href,
|
|
502
|
-
proxy: this.proxy
|
|
503
|
-
}, 'using proxy @{proxy} for @{url}');
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
exports.ProxyStorage = ProxyStorage;
|
|
595
|
+
}]);
|
|
596
|
+
}();
|
|
508
597
|
//# sourceMappingURL=proxy.js.map
|