From f7414e9bb22c6a0218db3eba636ba0d9438f242d Mon Sep 17 00:00:00 2001 From: "Juan Picado @jotadeveloper" Date: Sun, 4 Feb 2018 02:24:38 +0100 Subject: [PATCH] chore(flow): update flow definitions for proxy --- package.json | 2 +- src/lib/storage.js | 4 +- src/lib/up-storage.js | 97 ++++++++++++++++++++-------- test/functional/sanity/racycrash.js | 17 +++-- test/unit/up-storage.spec.js | 2 +- yarn.lock | Bin 318914 -> 318914 bytes 6 files changed, 82 insertions(+), 40 deletions(-) diff --git a/package.json b/package.json index 2f5684ee1..dd15499f6 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "@commitlint/cli": "^6.1.0", "@commitlint/config-conventional": "^6.1.0", "@commitlint/travis-cli": "^6.1.0", - "@verdaccio/types": "0.3.0", + "@verdaccio/types": "0.3.1", "axios": "0.17.1", "babel-cli": "6.26.0", "babel-core": "6.26.0", diff --git a/src/lib/storage.js b/src/lib/storage.js index e915c0c99..bc07346e9 100644 --- a/src/lib/storage.js +++ b/src/lib/storage.js @@ -570,7 +570,8 @@ class Storage implements IStorageHandler { } if (err || !upLinkResponse) { - return cb(null, [err || Error(500, 'no data')]); + // $FlowFixMe + return cb(null, [err || Error('no data')]); } try { @@ -597,6 +598,7 @@ class Storage implements IStorageHandler { try { Storage._mergeVersions(packageInfo, upLinkResponse, self.config); + } catch(err) { self.logger.error({ sub: 'out', diff --git a/src/lib/up-storage.js b/src/lib/up-storage.js index 7c9eb9adf..7154ea9d6 100644 --- a/src/lib/up-storage.js +++ b/src/lib/up-storage.js @@ -1,3 +1,5 @@ +// @flow + import zlib from 'zlib'; import JSONStream from 'JSONStream'; import createError from 'http-errors'; @@ -8,7 +10,17 @@ import URL from 'url'; import {parseInterval, is_object, ErrorCode} from './utils'; import {ReadTarball} from '@verdaccio/streams'; -const Logger = require('./logger'); +import type { + IProxy, + Config, + Callback, + Logger, +} from '@verdaccio/types'; + +import type {IUploadTarball} from '@verdaccio/streams'; + + +const LoggerApi = require('./logger'); const encode = function(thing) { return encodeURIComponent(thing).replace(/^%40/, '@'); @@ -33,23 +45,37 @@ const setConfig = (config, key, def) => { * Implements Storage interface * (same for storage.js, local-storage.js, up-storage.js) */ -class ProxyStorage { +class ProxyStorage implements IProxy { + config: Config; + failed_requests: number; + userAgent: string; + ca: string | void; + logger: Logger; + server_id: string; + url: any; + maxage: string; + timeout: string; + max_fails: number; + fail_timeout: number; + upname: string; + proxy: string; + last_request_time: number; /** * Constructor * @param {*} config * @param {*} mainConfig */ - constructor(config, mainConfig) { + constructor(config: UpLinkConf, mainConfig: Config) { this.config = config; this.failed_requests = 0; this.userAgent = mainConfig.user_agent; this.ca = config.ca; - this.logger = Logger.logger.child({sub: 'out'}); + this.logger = LoggerApi.logger.child({sub: 'out'}); this.server_id = mainConfig.server_id; this.url = URL.parse(this.config.url); - + // $FlowFixMe this._setupProxy(this.url.hostname, config, mainConfig, this.url.protocol === 'https:'); this.config.url = this.config.url.replace(/\/$/, ''); @@ -74,7 +100,7 @@ class ProxyStorage { * @param {*} cb * @return {Request} */ - request(options, cb) { + request(options: any, cb: Callback) { let json; if (this._statusCheck() === false) { @@ -84,9 +110,10 @@ class ProxyStorage { if (_.isFunction(cb)) { cb(ErrorCode.get500('uplink is offline')); } + // $FlowFixMe streamRead.emit('error', createError('uplink is offline')); }); - + // $FlowFixMe streamRead._read = function() {}; // preventing 'Uncaught, unspecified "error" event' streamRead.on('error', function() {}); @@ -116,7 +143,7 @@ class ProxyStorage { let requestCallback = cb ? (function(err, res, body) { let error; const responseLength = err ? 0 : body.length; - + // $FlowFixMe processBody(err, body); logActivity(); cb(err, res, body); @@ -132,6 +159,7 @@ class ProxyStorage { if (options.json && res.statusCode < 300) { try { + // $FlowFixMe body = JSON.parse(body.toString('utf8')); } catch(_err) { body = {}; @@ -216,7 +244,7 @@ class ProxyStorage { * @return {Object} * @private */ - _setHeaders(options) { + _setHeaders(options: any) { const headers = options.headers || {}; const accept = 'Accept'; const acceptEncoding = 'Accept-Encoding'; @@ -236,7 +264,7 @@ class ProxyStorage { * @return {Object} * @private */ - _setAuth(headers) { + _setAuth(headers: any) { if (_.isNil(this.config.auth) || headers['authorization']) { return headers; @@ -248,7 +276,7 @@ class ProxyStorage { // get NPM_TOKEN http://blog.npmjs.org/post/118393368555/deploying-with-npm-private-modules // or get other variable export in env - let token = process.env.NPM_TOKEN; + let token: any = process.env.NPM_TOKEN; if (this.config.auth.token) { token = this.config.auth.token; } else if (this.config.auth.token_env) { @@ -270,7 +298,7 @@ class ProxyStorage { * @throws {Error} * @private */ - _throwErrorAuth(message) { + _throwErrorAuth(message: string) { this.logger.error(message); throw new Error(message); } @@ -282,7 +310,7 @@ class ProxyStorage { * @param {string} token * @private */ - _setHeaderAuthorization(headers, type, token) { + _setHeaderAuthorization(headers: any, type: string, token: string) { if (type !== 'bearer' && type !== 'basic') { this._throwErrorAuth(`Auth type '${type}' not allowed`); } @@ -310,7 +338,7 @@ class ProxyStorage { * @param {Object} headers * @private */ - _overrideWithUplinkConfigHeaders(headers) { + _overrideWithUplinkConfigHeaders(headers: any) { // add/override headers specified in the config for (let key in this.config.headers) { if (Object.prototype.hasOwnProperty.call(this.config.headers, key)) { @@ -320,13 +348,15 @@ class ProxyStorage { } /** - * Determine whether can fetch from the provided URL. + * Determine whether can fetch from the provided URL * @param {*} url * @return {Boolean} */ - isUplinkValid(url) { - url = URL.parse(url); - return url.protocol === this.url.protocol && url.host === this.url.host && url.path.indexOf(this.url.path) === 0; + isUplinkValid(url: string) { + // $FlowFixMe + url = URL.parse(url); + // $FlowFixMe + return url.protocol === this.url.protocol && url.host === this.url.host && url.path.indexOf(this.url.path) === 0; } /** @@ -335,7 +365,7 @@ class ProxyStorage { * @param {*} options request options, eg: eTag. * @param {*} callback */ - getRemoteMetadata(name, options, callback) { + getRemoteMetadata(name: string, options: any, callback: Callback) { const headers = {}; if (_.isNil(options.etag) === false) { headers['If-None-Match'] = options.etag; @@ -355,7 +385,9 @@ class ProxyStorage { return callback( ErrorCode.get404('package doesn\'t exist on uplink')); } if (!(res.statusCode >= 200 && res.statusCode < 300)) { + // $FlowFixMe const error = createError(`bad status code: ${res.statusCode}`); + // $FlowFixMe error.remoteStatus = res.statusCode; return callback(error); } @@ -368,7 +400,7 @@ class ProxyStorage { * @param {String} url * @return {Stream} */ - fetchTarball(url) { + fetchTarball(url: string) { const stream = new ReadTarball({}); let current_length = 0; let expected_length; @@ -382,11 +414,12 @@ class ProxyStorage { }, }); - readStream.on('response', function(res) { + readStream.on('response', function(res: any) { if (res.statusCode === 404) { return stream.emit('error', ErrorCode.get404('file doesn\'t exist on uplink')); } if (!(res.statusCode >= 200 && res.statusCode < 300)) { + // $FlowFixMe return stream.emit('error', createError('bad uplink status code: ' + res.statusCode)); } if (res.headers['content-length']) { @@ -408,6 +441,7 @@ class ProxyStorage { current_length += data.length; } if (expected_length && current_length != expected_length) { + // $FlowFixMe stream.emit('error', createError('content length mismatch')); } }); @@ -419,9 +453,9 @@ class ProxyStorage { * @param {*} options request options * @return {Stream} */ - search(options) { - const transformStream = new Stream.PassThrough({objectMode: true}); - const requestStream = this.request({ + search(options: any) { + const transformStream: IUploadTarball = new Stream.PassThrough({objectMode: true}); + const requestStream: IUploadTarball = this.request({ uri: options.req.url, req: options.req, headers: { @@ -437,6 +471,7 @@ class ProxyStorage { requestStream.on('response', (res) => { if (!String(res.statusCode).match(/^2\d\d$/)) { + // $FlowFixMe return transformStream.emit('error', createError(`bad status code ${res.statusCode} from uplink`)); } @@ -471,7 +506,7 @@ class ProxyStorage { * @param {*} req the http request * @param {*} headers the request headers */ - _addProxyHeaders(req, headers) { + _addProxyHeaders(req: any, headers: any) { if (req) { // Only submit X-Forwarded-For field if we don't have a proxy selected // in the config file. @@ -502,7 +537,7 @@ class ProxyStorage { * @param {*} alive * @return {Boolean} */ - _statusCheck(alive) { + _statusCheck(alive?: boolean) { if (arguments.length === 0) { return this._ifRequestFailure() === false; } else { @@ -541,9 +576,9 @@ class ProxyStorage { * @param {*} mainconfig * @param {*} isHTTPS */ - _setupProxy(hostname, config, mainconfig, isHTTPS) { + _setupProxy(hostname: string, config: UpLinkConf, mainconfig: Config, isHTTPS: boolean) { let noProxyList; - let proxy_key = isHTTPS ? 'https_proxy' : 'http_proxy'; + let proxy_key: string = isHTTPS ? 'https_proxy' : 'http_proxy'; // get http_proxy and no_proxy configs if (proxy_key in config) { @@ -552,6 +587,7 @@ class ProxyStorage { this.proxy = mainconfig[proxy_key]; } if ('no_proxy' in config) { + // $FlowFixMe noProxyList = config.no_proxy; } else if ('no_proxy' in mainconfig) { noProxyList = mainconfig.no_proxy; @@ -561,17 +597,22 @@ class ProxyStorage { if (hostname[0] !== '.') { hostname = '.' + hostname; } + // $FlowFixMe if (_.isString(noProxyList) && noProxyList.length) { + // $FlowFixMe noProxyList = noProxyList.split(','); } if (_.isArray(noProxyList)) { + // $FlowFixMe for (let i = 0; i < noProxyList.length; i++) { + // $FlowFixMe let noProxyItem = noProxyList[i]; if (noProxyItem[0] !== '.') noProxyItem = '.' + noProxyItem; if (hostname.lastIndexOf(noProxyItem) === hostname.length - noProxyItem.length) { if (this.proxy) { this.logger.debug({url: this.url.href, rule: noProxyItem}, 'not using proxy for @{url}, excluded by @{rule} rule'); + // $FlowFixMe this.proxy = false; } break; diff --git a/test/functional/sanity/racycrash.js b/test/functional/sanity/racycrash.js index 47d9fd10b..208e1a00e 100644 --- a/test/functional/sanity/racycrash.js +++ b/test/functional/sanity/racycrash.js @@ -1,9 +1,7 @@ -import assert from 'assert'; - export default function(server, express) { describe('test for unexpected client hangs', () => { - let on_tarball; + let handleResponseTarball; beforeAll(function() { express.get('/testexp-racycrash', function(request, response) { @@ -23,16 +21,17 @@ export default function(server, express) { }); express.get('/testexp-racycrash/-/test.tar.gz', function(request, response) { - on_tarball(response); + handleResponseTarball(response); }); }); test('should not crash on error if client disconnects', callback => { - on_tarball = function(res) { + handleResponseTarball = function(res) { res.header('content-length', 1e6); - res.write('test test test\n'); + res.write('test test test'); setTimeout(function() { - res.write('test test test\n'); + res.write('-'); + // destroy the connection res.socket.destroy(); cb(); }, 200); @@ -40,7 +39,7 @@ export default function(server, express) { server.request({uri: '/testexp-racycrash/-/test.tar.gz'}) .then(function(body) { - assert.equal(body, 'test test test\n'); + expect(body).toEqual('test test test'); }); function cb() { @@ -54,7 +53,7 @@ export default function(server, express) { }); test('should not store tarball', () => { - on_tarball = function(res) { + handleResponseTarball = function(res) { res.socket.destroy(); }; diff --git a/test/unit/up-storage.spec.js b/test/unit/up-storage.spec.js index cc857e3a6..7ee13b400 100644 --- a/test/unit/up-storage.spec.js +++ b/test/unit/up-storage.spec.js @@ -13,7 +13,7 @@ describe('UpStorge', () => { const uplinkDefault = { url: 'https://registry.npmjs.org/' }; - let generateProxy = (config = uplinkDefault) => { + let generateProxy = (config: UpLinkConf = uplinkDefault) => { const appConfig: Config = new AppConfig(configExample); return new ProxyStorage(config, appConfig); diff --git a/yarn.lock b/yarn.lock index 2e11e8aa40178bac6a3c4210d81ac081ba038abd..59643fd6b09ce01e470f062cba3850d329345e1c 100644 GIT binary patch delta 89 zcmX@KTlmm!;SHZ;m<*MsU(8~%o~$n`t7oWJl3t~pl4hQoVr-d`oRVZ qWNdC?ZjoY?Y-x~cY;0j+m}HUKTqWCHCCdoJOhC-My-JqF;{X6m_8f8m delta 89 zcmX@KTlmm!;SHZ;m<*Jr2iCAyPu7=})icm5Nv~42Of*b0Hb_ZMGfqr2u{1DBPDwGd pOiKe&Cdp=o$;n1Z7AYy_Mv2W;vh7u}j6lo;#LU~PWLZ28002S}9O3`~