mirror of
https://github.com/pnpm/pnpm.git
synced 2026-05-04 05:56:24 -04:00
@@ -39,6 +39,7 @@
|
||||
"@pnpm/npm-resolver": "^0.3.9",
|
||||
"@pnpm/tarball-fetcher": "^0.3.1",
|
||||
"@types/tape": "^4.2.31",
|
||||
"is-port-reachable": "^2.0.0",
|
||||
"mos": "^2.0.0-alpha.3",
|
||||
"mos-plugin-readme": "^1.0.4",
|
||||
"package-preview": "^1.0.1",
|
||||
|
||||
@@ -13,6 +13,7 @@ devDependencies:
|
||||
'@pnpm/npm-resolver': 0.3.11
|
||||
'@pnpm/tarball-fetcher': 0.3.3
|
||||
'@types/tape': 4.2.31
|
||||
is-port-reachable: 2.0.0
|
||||
mos: 2.0.0-alpha.3
|
||||
mos-plugin-readme: 1.0.4
|
||||
package-preview: 1.0.4
|
||||
@@ -1711,6 +1712,12 @@ packages:
|
||||
node: '>=0.10.0'
|
||||
resolution:
|
||||
integrity: sha1-caUMhCnfync8kqOQpKA7OfzVHT4=
|
||||
/is-port-reachable/2.0.0:
|
||||
dev: true
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha1-VNE9ZUkX60M64+4ty8N3TyzUTrI=
|
||||
/is-promise/2.1.0:
|
||||
dev: true
|
||||
resolution:
|
||||
@@ -4000,6 +4007,7 @@ specifiers:
|
||||
'@types/tape': ^4.2.31
|
||||
'@types/uuid': ^3.4.3
|
||||
got: ^8.0.1
|
||||
is-port-reachable: ^2.0.0
|
||||
mos: ^2.0.0-alpha.3
|
||||
mos-plugin-readme: ^1.0.4
|
||||
p-limit: ^1.1.0
|
||||
|
||||
@@ -10,12 +10,16 @@ import pLimit = require('p-limit')
|
||||
import {StoreController} from 'package-store'
|
||||
import uuid = require('uuid')
|
||||
|
||||
export type StoreServerController = StoreController & {
|
||||
stop (): Promise<void>,
|
||||
}
|
||||
|
||||
export default function (
|
||||
initOpts: {
|
||||
remotePrefix: string,
|
||||
concurrency?: number,
|
||||
},
|
||||
): Promise<StoreController> {
|
||||
): Promise<StoreServerController> {
|
||||
const remotePrefix = initOpts.remotePrefix
|
||||
const limitedFetch = fetch.bind(null, pLimit(initOpts.concurrency || 100))
|
||||
|
||||
@@ -39,6 +43,7 @@ export default function (
|
||||
saveState: async () => {
|
||||
await limitedFetch(`${remotePrefix}/saveState`, {})
|
||||
},
|
||||
stop: () => limitedFetch(`${remotePrefix}/stop`, {}),
|
||||
updateConnections: async (prefix: string, opts: {addDependencies: string[], removeDependencies: string[], prune: boolean}) => {
|
||||
await limitedFetch(`${remotePrefix}/updateConnections`, {
|
||||
opts,
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import logger from '@pnpm/logger'
|
||||
import {
|
||||
RequestPackageOptions,
|
||||
WantedDependency,
|
||||
} from '@pnpm/package-requester'
|
||||
import http = require('http')
|
||||
import {IncomingMessage, Server, ServerResponse} from 'http'
|
||||
|
||||
import {RequestPackageOptions, WantedDependency} from '@pnpm/package-requester'
|
||||
import {StoreController} from 'package-store'
|
||||
|
||||
interface RequestBody {
|
||||
@@ -22,6 +25,7 @@ export default function (
|
||||
path?: string,
|
||||
port?: number,
|
||||
hostname?: string,
|
||||
ignoreStopRequests?: boolean,
|
||||
},
|
||||
) {
|
||||
const manifestPromises = {}
|
||||
@@ -97,6 +101,17 @@ export default function (
|
||||
await store.importPackage(importPackageBody.from, importPackageBody.to, importPackageBody.opts)
|
||||
res.end(JSON.stringify('OK'))
|
||||
break
|
||||
case '/stop':
|
||||
if (opts.ignoreStopRequests) {
|
||||
res.statusCode = 403
|
||||
res.end()
|
||||
break
|
||||
}
|
||||
logger.info('Got request to stop the server')
|
||||
await close()
|
||||
res.end(JSON.stringify('OK'))
|
||||
logger.info('Server stopped')
|
||||
break
|
||||
default:
|
||||
res.statusCode = 404
|
||||
res.end(`${req.url} does not match any route`)
|
||||
@@ -114,7 +129,10 @@ export default function (
|
||||
listener = server.listen(opts.port, opts.hostname)
|
||||
}
|
||||
|
||||
return {
|
||||
close: () => listener.close(() => { return }),
|
||||
return { close }
|
||||
|
||||
function close () {
|
||||
listener.close()
|
||||
return store.close()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,15 @@ import {
|
||||
import {
|
||||
PackageFilesResponse,
|
||||
} from '@pnpm/package-requester'
|
||||
import got = require('got')
|
||||
import isPortReachable = require('is-port-reachable')
|
||||
import createResolver from '@pnpm/npm-resolver'
|
||||
import createFetcher from '@pnpm/tarball-fetcher'
|
||||
import createStore from 'package-store'
|
||||
|
||||
test('server', async t => {
|
||||
const registry = 'https://registry.npmjs.org/'
|
||||
const registry = 'https://registry.npmjs.org/'
|
||||
|
||||
async function createStoreController () {
|
||||
const rawNpmConfig = { registry }
|
||||
const store = '.store'
|
||||
const resolve = createResolver({
|
||||
@@ -25,16 +28,19 @@ test('server', async t => {
|
||||
strictSsl: true,
|
||||
rawNpmConfig,
|
||||
})
|
||||
const storeCtrlForServer = await createStore(resolve, fetchers, {
|
||||
return await createStore(resolve, fetchers, {
|
||||
networkConcurrency: 1,
|
||||
store: store,
|
||||
locks: undefined,
|
||||
lockStaleDuration: 100,
|
||||
})
|
||||
}
|
||||
|
||||
test('server', async t => {
|
||||
const port = 5813
|
||||
const hostname = '127.0.0.1'
|
||||
const remotePrefix = `http://${hostname}:${port}`
|
||||
const storeCtrlForServer = await createStoreController()
|
||||
const server = createServer(storeCtrlForServer, {
|
||||
port,
|
||||
hostname,
|
||||
@@ -45,7 +51,6 @@ test('server', async t => {
|
||||
{
|
||||
downloadPriority: 0,
|
||||
loggedPkg: {rawSpec: 'sfdf'},
|
||||
offline: false,
|
||||
prefix: process.cwd(),
|
||||
registry,
|
||||
verifyStoreIntegrity: false,
|
||||
@@ -65,7 +70,55 @@ test('server', async t => {
|
||||
|
||||
await response['finishing']
|
||||
|
||||
server.close()
|
||||
await server.close()
|
||||
await storeCtrl.close()
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('stop server with remote call', async t => {
|
||||
const port = 5813
|
||||
const hostname = '127.0.0.1'
|
||||
const remotePrefix = `http://${hostname}:${port}`
|
||||
const storeCtrlForServer = await createStoreController()
|
||||
const server = createServer(storeCtrlForServer, {
|
||||
port,
|
||||
hostname,
|
||||
ignoreStopRequests: false,
|
||||
})
|
||||
|
||||
t.ok(await isPortReachable(port), 'server is running')
|
||||
|
||||
const response = await got(`${remotePrefix}/stop`, {method: 'POST'})
|
||||
|
||||
t.equal(response.statusCode, 200, 'success returned by server stopping endpoint')
|
||||
|
||||
t.notOk(await isPortReachable(port), 'server is not running')
|
||||
|
||||
t.end()
|
||||
})
|
||||
|
||||
test('disallow stop server with remote call', async t => {
|
||||
const port = 5813
|
||||
const hostname = '127.0.0.1'
|
||||
const remotePrefix = `http://${hostname}:${port}`
|
||||
const storeCtrlForServer = await createStoreController()
|
||||
const server = createServer(storeCtrlForServer, {
|
||||
port,
|
||||
hostname,
|
||||
ignoreStopRequests: true,
|
||||
})
|
||||
|
||||
t.ok(await isPortReachable(port), 'server is running')
|
||||
|
||||
try {
|
||||
const response = await got(`${remotePrefix}/stop`, {method: 'POST'})
|
||||
t.fail('request should have failed')
|
||||
} catch (err) {
|
||||
t.equal(err.statusCode, 403, 'server not stopped')
|
||||
}
|
||||
|
||||
t.ok(await isPortReachable(port), 'server is running')
|
||||
|
||||
await server.close()
|
||||
t.end()
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user