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

View File

@ -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

View File

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

View File

@ -10,6 +10,7 @@ import { IAuth } from '@verdaccio/auth';
import { Storage } from '@verdaccio/store';
import { Config } from '@verdaccio/types';
import bodyParser from 'body-parser';
import semver from 'semver';
import whoami from './whoami';
import ping from './ping';
@ -23,6 +24,10 @@ import profile from './v1/profile';
import token from './v1/token';
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 {
/* eslint new-cap:off */
const app = express.Router();

View File

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

View File

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

View File

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

View File

@ -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';

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -88,6 +88,12 @@ export class SearchManager {
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[]> {
const transformResults = new TransFormResults({ objectMode: true });
const streamPassThrough = new PassThrough({ objectMode: true });
@ -148,9 +154,7 @@ export class SearchManager {
options: ProxySearchParams,
searchPassThrough: PassThrough
): Promise<any> {
// TODO: review how to handle abort
const abortController = new AbortController();
return uplink.search({ ...options, abort: abortController }).then((bodyStream) => {
return uplink.search({ ...options }).then((bodyStream) => {
bodyStream.pipe(searchPassThrough, { end: false });
bodyStream.on('error', (err: VerdaccioError): void => {
logger.error(

View File

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