1
0
mirror of https://github.com/verdaccio/verdaccio.git synced 2024-12-24 21:15:51 +01:00

abort search request support for proxy (#2474)

* update undici

* abort search request support for proxy
This commit is contained in:
Juan Picado 2021-10-15 23:00:30 +02:00 committed by GitHub
parent 794af76c50
commit b702ea3631
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 72 additions and 25 deletions

@ -0,0 +1,10 @@
---
'@verdaccio/api': minor
'@verdaccio/fastify-migration': minor
'@verdaccio/hooks': minor
'@verdaccio/logger-prettify': minor
'@verdaccio/proxy': minor
'@verdaccio/store': minor
---
abort search request support for proxy

@ -48,6 +48,7 @@
"@verdaccio/store": "workspace:6.0.0-6-next.13", "@verdaccio/store": "workspace:6.0.0-6-next.13",
"@verdaccio/tarball": "workspace:11.0.0-6-next.7", "@verdaccio/tarball": "workspace:11.0.0-6-next.7",
"@verdaccio/utils": "workspace:6.0.0-6-next.6", "@verdaccio/utils": "workspace:6.0.0-6-next.6",
"abortcontroller-polyfill": "1.7.3",
"cookies": "0.8.0", "cookies": "0.8.0",
"debug": "4.3.2", "debug": "4.3.2",
"express": "4.17.1", "express": "4.17.1",

@ -10,6 +10,7 @@ import { IAuth } from '@verdaccio/auth';
import { Storage } from '@verdaccio/store'; import { Storage } from '@verdaccio/store';
import { Config } from '@verdaccio/types'; import { Config } from '@verdaccio/types';
import bodyParser from 'body-parser'; import bodyParser from 'body-parser';
import semver from 'semver';
import whoami from './whoami'; import whoami from './whoami';
import ping from './ping'; import ping from './ping';
@ -23,6 +24,10 @@ import profile from './v1/profile';
import token from './v1/token'; import token from './v1/token';
import v1Search from './v1/search'; import v1Search from './v1/search';
if (semver.lte(process.version, 'v15.0.0')) {
global.AbortController = require('abortcontroller-polyfill/dist/cjs-ponyfill').AbortController;
}
export default function (config: Config, auth: IAuth, storage: Storage): Router { export default function (config: Config, auth: IAuth, storage: Storage): Router {
/* eslint new-cap:off */ /* eslint new-cap:off */
const app = express.Router(); const app = express.Router();

@ -35,16 +35,23 @@ export default function (route, auth: IAuth, storage: Storage): void {
} }
route.get('/-/v1/search', async (req, res, next) => { route.get('/-/v1/search', async (req, res, next) => {
let [size, from] = ['size', 'from'].map((k) => req.query[k]); const { query, url } = req;
let [size, from] = ['size', 'from'].map((k) => query[k]);
let data; let data;
const abort = new AbortController();
req.on('aborted', () => {
abort.abort();
});
size = parseInt(size, 10) || 20; size = parseInt(size, 10) || 20;
from = parseInt(from, 10) || 0; from = parseInt(from, 10) || 0;
try { try {
data = await storage.searchManager?.search({ data = await storage.searchManager?.search({
query: req.query, query,
url: req.url, url,
abort,
}); });
debug('stream finish'); debug('stream finish');
const checkAccessPromises: searchUtils.SearchItemPkg[] = await Promise.all( const checkAccessPromises: searchUtils.SearchItemPkg[] = await Promise.all(

@ -38,10 +38,12 @@
"@verdaccio/auth": "workspace:6.0.0-6-next.12", "@verdaccio/auth": "workspace:6.0.0-6-next.12",
"@verdaccio/logger": "workspace:6.0.0-6-next.5", "@verdaccio/logger": "workspace:6.0.0-6-next.5",
"@verdaccio/store": "workspace:6.0.0-6-next.13", "@verdaccio/store": "workspace:6.0.0-6-next.13",
"abortcontroller-polyfill": "1.7.3",
"core-js": "3.17.2", "core-js": "3.17.2",
"debug": "4.3.2", "debug": "4.3.2",
"fastify": "3.20.2", "fastify": "3.20.2",
"fastify-plugin": "3.0.0" "fastify-plugin": "3.0.0",
"semver": "7.3.5"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "16.9.1", "@types/node": "16.9.1",

@ -9,12 +9,18 @@ async function searchRoute(fastify) {
// TODO: add validations for query, some parameters are mandatory // TODO: add validations for query, some parameters are mandatory
// TODO: review which query fields are mandatory // TODO: review which query fields are mandatory
const abort = new AbortController();
request.on('aborted', () => {
abort.abort();
});
const { url, query } = request; const { url, query } = request;
const storage = fastify.storage; const storage = fastify.storage;
const data = await storage.searchManager?.search({ const data = await storage.searchManager?.search({
query: query, query,
url: url, url,
abort,
}); });
logger.http('search endpoint'); logger.http('search endpoint');

@ -1 +1,7 @@
import semver from 'semver';
if (semver.lte(process.version, 'v15.0.0')) {
global.AbortController = require('abortcontroller-polyfill/dist/cjs-ponyfill').AbortController;
}
export { default } from './server'; export { default } from './server';

@ -35,7 +35,7 @@
"core-js": "3.17.2", "core-js": "3.17.2",
"debug": "4.3.2", "debug": "4.3.2",
"handlebars": "4.7.7", "handlebars": "4.7.7",
"undici": "4.4.7", "undici": "4.7.3",
"undici-fetch": "1.0.0-rc.4" "undici-fetch": "1.0.0-rc.4"
}, },
"devDependencies": { "devDependencies": {

@ -26,7 +26,7 @@
"verdaccio" "verdaccio"
], ],
"engines": { "engines": {
"node": ">=10", "node": ">=14",
"npm": ">=6" "npm": ">=6"
}, },
"scripts": { "scripts": {

@ -26,7 +26,7 @@
"verdaccio" "verdaccio"
], ],
"engines": { "engines": {
"node": ">=10", "node": ">=14",
"npm": ">=6" "npm": ">=6"
}, },
"scripts": { "scripts": {
@ -51,7 +51,7 @@
"lodash": "4.17.20", "lodash": "4.17.20",
"node-fetch": "2.6.1", "node-fetch": "2.6.1",
"request": "2.87.0", "request": "2.87.0",
"undici": "4.4.7", "undici": "4.7.3",
"undici-fetch": "1.0.0-rc.4" "undici-fetch": "1.0.0-rc.4"
}, },
"devDependencies": { "devDependencies": {

@ -54,7 +54,7 @@ export type ProxySearchParams = {
headers?: Headers; headers?: Headers;
url: string; url: string;
query?: searchUtils.SearchQuery; query?: searchUtils.SearchQuery;
abort?: AbortController; abort: AbortController;
}; };
export interface IProxy { export interface IProxy {
config: UpLinkConfLocal; config: UpLinkConfLocal;

@ -61,7 +61,7 @@
"@types/node": "16.9.1", "@types/node": "16.9.1",
"@verdaccio/mock": "workspace:6.0.0-6-next.9", "@verdaccio/mock": "workspace:6.0.0-6-next.9",
"@verdaccio/types": "workspace:11.0.0-6-next.8", "@verdaccio/types": "workspace:11.0.0-6-next.8",
"undici": "4.4.7", "undici": "4.7.3",
"undici-fetch": "1.0.0-rc.4", "undici-fetch": "1.0.0-rc.4",
"tmp-promise": "3.0.2" "tmp-promise": "3.0.2"
}, },

@ -88,6 +88,12 @@ export class SearchManager {
return uplinksList; return uplinksList;
} }
/**
* Handle search on packages and proxies.
* Iterate all proxies configured and search in all endpoints in v2 and pipe all responses
* to a stream, once the proxies request has finished search in local storage for all packages
* (privated and cached).
*/
public async search(options: ProxySearchParams): Promise<searchUtils.SearchPackageItem[]> { public async search(options: ProxySearchParams): Promise<searchUtils.SearchPackageItem[]> {
const transformResults = new TransFormResults({ objectMode: true }); const transformResults = new TransFormResults({ objectMode: true });
const streamPassThrough = new PassThrough({ objectMode: true }); const streamPassThrough = new PassThrough({ objectMode: true });
@ -148,9 +154,7 @@ export class SearchManager {
options: ProxySearchParams, options: ProxySearchParams,
searchPassThrough: PassThrough searchPassThrough: PassThrough
): Promise<any> { ): Promise<any> {
// TODO: review how to handle abort return uplink.search({ ...options }).then((bodyStream) => {
const abortController = new AbortController();
return uplink.search({ ...options, abort: abortController }).then((bodyStream) => {
bodyStream.pipe(searchPassThrough, { end: false }); bodyStream.pipe(searchPassThrough, { end: false });
bodyStream.on('error', (err: VerdaccioError): void => { bodyStream.on('error', (err: VerdaccioError): void => {
logger.error( logger.error(

26
pnpm-lock.yaml generated

@ -199,6 +199,7 @@ importers:
'@verdaccio/tarball': workspace:11.0.0-6-next.7 '@verdaccio/tarball': workspace:11.0.0-6-next.7
'@verdaccio/types': workspace:11.0.0-6-next.8 '@verdaccio/types': workspace:11.0.0-6-next.8
'@verdaccio/utils': workspace:6.0.0-6-next.6 '@verdaccio/utils': workspace:6.0.0-6-next.6
abortcontroller-polyfill: 1.7.3
body-parser: 1.19.0 body-parser: 1.19.0
cookies: 0.8.0 cookies: 0.8.0
debug: 4.3.2 debug: 4.3.2
@ -217,6 +218,7 @@ importers:
'@verdaccio/store': link:../store '@verdaccio/store': link:../store
'@verdaccio/tarball': link:../core/tarball '@verdaccio/tarball': link:../core/tarball
'@verdaccio/utils': link:../utils '@verdaccio/utils': link:../utils
abortcontroller-polyfill: 1.7.3
cookies: 0.8.0 cookies: 0.8.0
debug: 4.3.2 debug: 4.3.2
express: 4.17.1 express: 4.17.1
@ -413,20 +415,24 @@ importers:
'@verdaccio/logger': workspace:6.0.0-6-next.5 '@verdaccio/logger': workspace:6.0.0-6-next.5
'@verdaccio/store': workspace:6.0.0-6-next.13 '@verdaccio/store': workspace:6.0.0-6-next.13
'@verdaccio/types': workspace:11.0.0-6-next.8 '@verdaccio/types': workspace:11.0.0-6-next.8
abortcontroller-polyfill: 1.7.3
core-js: 3.17.2 core-js: 3.17.2
debug: 4.3.2 debug: 4.3.2
fastify: 3.20.2 fastify: 3.20.2
fastify-plugin: 3.0.0 fastify-plugin: 3.0.0
semver: 7.3.5
ts-node: 10.2.1 ts-node: 10.2.1
dependencies: dependencies:
'@verdaccio/auth': link:../../auth '@verdaccio/auth': link:../../auth
'@verdaccio/config': link:../../config '@verdaccio/config': link:../../config
'@verdaccio/logger': link:../../logger '@verdaccio/logger': link:../../logger
'@verdaccio/store': link:../../store '@verdaccio/store': link:../../store
abortcontroller-polyfill: 1.7.3
core-js: 3.17.2 core-js: 3.17.2
debug: 4.3.2 debug: 4.3.2
fastify: 3.20.2 fastify: 3.20.2
fastify-plugin: 3.0.0 fastify-plugin: 3.0.0
semver: 7.3.5
devDependencies: devDependencies:
'@types/node': 16.9.1 '@types/node': 16.9.1
'@verdaccio/types': link:../types '@verdaccio/types': link:../types
@ -491,7 +497,7 @@ importers:
core-js: 3.17.2 core-js: 3.17.2
debug: 4.3.2 debug: 4.3.2
handlebars: 4.7.7 handlebars: 4.7.7
undici: 4.4.7 undici: 4.7.3
undici-fetch: 1.0.0-rc.4 undici-fetch: 1.0.0-rc.4
dependencies: dependencies:
'@verdaccio/core': link:../core/core '@verdaccio/core': link:../core/core
@ -499,7 +505,7 @@ importers:
core-js: 3.17.2 core-js: 3.17.2
debug: 4.3.2 debug: 4.3.2
handlebars: 4.7.7 handlebars: 4.7.7
undici: 4.4.7 undici: 4.7.3
undici-fetch: 1.0.0-rc.4 undici-fetch: 1.0.0-rc.4
devDependencies: devDependencies:
'@types/node': 16.9.1 '@types/node': 16.9.1
@ -915,7 +921,7 @@ importers:
node-mocks-http: 1.10.1 node-mocks-http: 1.10.1
request: 2.87.0 request: 2.87.0
semver: 7.3.5 semver: 7.3.5
undici: 4.4.7 undici: 4.7.3
undici-fetch: 1.0.0-rc.4 undici-fetch: 1.0.0-rc.4
dependencies: dependencies:
'@verdaccio/config': link:../config '@verdaccio/config': link:../config
@ -930,7 +936,7 @@ importers:
lodash: 4.17.20 lodash: 4.17.20
node-fetch: 2.6.1 node-fetch: 2.6.1
request: 2.87.0 request: 2.87.0
undici: 4.4.7 undici: 4.7.3
undici-fetch: 1.0.0-rc.4 undici-fetch: 1.0.0-rc.4
devDependencies: devDependencies:
'@types/node': 16.9.1 '@types/node': 16.9.1
@ -1032,7 +1038,7 @@ importers:
merge2: 1.4.1 merge2: 1.4.1
semver: 7.1.2 semver: 7.1.2
tmp-promise: 3.0.2 tmp-promise: 3.0.2
undici: 4.4.7 undici: 4.7.3
undici-fetch: 1.0.0-rc.4 undici-fetch: 1.0.0-rc.4
dependencies: dependencies:
'@verdaccio/config': link:../config '@verdaccio/config': link:../config
@ -1057,7 +1063,7 @@ importers:
'@verdaccio/mock': link:../mock '@verdaccio/mock': link:../mock
'@verdaccio/types': link:../core/types '@verdaccio/types': link:../core/types
tmp-promise: 3.0.2 tmp-promise: 3.0.2
undici: 4.4.7 undici: 4.7.3
undici-fetch: 1.0.0-rc.4 undici-fetch: 1.0.0-rc.4
packages/tools/benchmark: packages/tools/benchmark:
@ -20049,14 +20055,14 @@ packages:
dependencies: dependencies:
undici: 4.5.1 undici: 4.5.1
/undici/4.4.7:
resolution: {integrity: sha512-41YDu0wuKPhvd2oPDHRe0ufai70O8nOyL6vgpWkv1DUPTwOx59GhZVRvZwinBLAiKJHta/91gSb7wmrDghuJIw==}
engines: {node: '>=12.18'}
/undici/4.5.1: /undici/4.5.1:
resolution: {integrity: sha512-1Kmphp4SMwVbSauz9xH4gxt0m3sLGs5qRHs/XYgjeO3bNSt6hspDZqMhM8+ETu9ynB5bq9e6mnwcDz+NVCQ3UQ==} resolution: {integrity: sha512-1Kmphp4SMwVbSauz9xH4gxt0m3sLGs5qRHs/XYgjeO3bNSt6hspDZqMhM8+ETu9ynB5bq9e6mnwcDz+NVCQ3UQ==}
engines: {node: '>=12.18'} engines: {node: '>=12.18'}
/undici/4.7.3:
resolution: {integrity: sha512-ecY0KLuZ3EVbiR+Z2kpxh3V3tLGhkxuNv5jhIYskZXO8KgpwcFxqScIMs6JO523VFnfRnN2Fm6yhLxc+BQvezw==}
engines: {node: '>=12.18'}
/unherit/1.1.3: /unherit/1.1.3:
resolution: {integrity: sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==} resolution: {integrity: sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==}
dependencies: dependencies: