Skip to content

Commit

Permalink
f
Browse files Browse the repository at this point in the history
  • Loading branch information
fengmk2 committed Dec 8, 2024
1 parent 48abebe commit 815eb45
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 86 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

- Fork the project, make a change, and send a pull request;
- Have a look at code style now before starting;
- Make sure the tests case (`$ make test`) pass before sending a pull request;
- Make sure the tests case (`$ npm test`) pass before sending a pull request;
16 changes: 5 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,18 +91,12 @@ Most likely network error, check that your `/etc/hosts` and make sure the conten
::1 localhost
```

<!-- GITCONTRIBUTOR_START -->

## Contributors

|[<img src="https://avatars.githubusercontent.com/u/1011681?v=4" width="100px;"/><br/><sub><b>xudafeng</b></sub>](https://github.com/xudafeng)<br/>|[<img src="https://avatars.githubusercontent.com/u/156269?v=4" width="100px;"/><br/><sub><b>fengmk2</b></sub>](https://github.com/fengmk2)<br/>|[<img src="https://avatars.githubusercontent.com/u/1044425?v=4" width="100px;"/><br/><sub><b>ziczhu</b></sub>](https://github.com/ziczhu)<br/>|[<img src="https://avatars.githubusercontent.com/u/810438?v=4" width="100px;"/><br/><sub><b>gaearon</b></sub>](https://github.com/gaearon)<br/>|[<img src="https://avatars.githubusercontent.com/u/34906299?v=4" width="100px;"/><br/><sub><b>chnliquan</b></sub>](https://github.com/chnliquan)<br/>|[<img src="https://avatars.githubusercontent.com/u/360661?v=4" width="100px;"/><br/><sub><b>popomore</b></sub>](https://github.com/popomore)<br/>|
| :---: | :---: | :---: | :---: | :---: | :---: |
[<img src="https://avatars.githubusercontent.com/u/52845048?v=4" width="100px;"/><br/><sub><b>snapre</b></sub>](https://github.com/snapre)<br/>|[<img src="https://avatars.githubusercontent.com/u/56271907?v=4" width="100px;"/><br/><sub><b>yavuzakyuz</b></sub>](https://github.com/yavuzakyuz)<br/>|[<img src="https://avatars.githubusercontent.com/u/197375?v=4" width="100px;"/><br/><sub><b>antife-yinyue</b></sub>](https://github.com/antife-yinyue)<br/>
## License

This project follows the git-contributor [spec](https://github.com/xudafeng/git-contributor), auto updated at `Wed Sep 21 2022 23:10:27 GMT+0800`.
[MIT](LICENSE)

<!-- GITCONTRIBUTOR_END -->
## Contributors

## License
[![Contributors](https://contrib.rocks/image?repo=node-modules/detect-port)](https://github.com/node-modules/detect-port/graphs/contributors)

[MIT](LICENSE)
Made with [contributors-img](https://contrib.rocks).
16 changes: 7 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@
},
"main": "./dist/commonjs/index.js",
"files": [
"bin",
"lib",
"index.js"
"dist",
"src"
],
"repository": {
"type": "git",
Expand All @@ -26,23 +25,21 @@
"devDependencies": {
"@eggjs/tsconfig": "^1.3.3",
"@types/mocha": "^10.0.6",
"@types/node": "^20.9.0",
"@types/node": "^22.10.1",
"egg-bin": "^6.9.0",
"eslint": "^8.52.0",
"eslint-config-egg": "^13.0.0",
"execa": "^8.0.1",
"git-contributor": "^2.1.5",
"mm": "^3.4.0",
"strip-ansi": "^7.1.0",
"ts-node": "^10.9.1",
"tshy": "^1.8.0",
"tshy": "^3.0.2",
"tshy-after": "^1.0.0",
"typescript": "^5.2.2"
},
"scripts": {
"test": "npm run lint -- --fix && egg-bin test",
"lint": "eslint src test --ext ts",
"ci": "npm run lint && npm run cov && npm run prepublishOnly",
"contributor": "git-contributor",
"prepublishOnly": "tshy && tshy-after",
"cov": "egg-bin cov"
},
Expand All @@ -69,5 +66,6 @@
}
},
"types": "./dist/commonjs/index.d.ts",
"type": "module"
"type": "module",
"module": "./dist/esm/index.js"
}
19 changes: 10 additions & 9 deletions src/detect-port.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import net from 'node:net';
import { ip } from 'address';
import { createServer, AddressInfo } from 'node:net';
import { debuglog } from 'node:util';
import { ip } from 'address';

const debug = debuglog('detect-port');

type DetectPortCallback = (err: Error | null, port: number) => void;
type DetectPortCallback = (err: Error | null, port?: number) => void;

interface PortConfig {
port?: number | string;
Expand Down Expand Up @@ -46,7 +46,7 @@ export default function detectPort(port?: number | string | PortConfig | DetectP
});
}

function tryListen(port: number, maxPort: number, hostname: string | undefined, callback: (...args: any[]) => void) {
function tryListen(port: number, maxPort: number, hostname: string | undefined, callback: DetectPortCallback) {
function handleError() {
port++;
if (port >= maxPort) {
Expand Down Expand Up @@ -109,10 +109,10 @@ function tryListen(port: number, maxPort: number, hostname: string | undefined,
}
}

function listen(port: number, hostname: string | undefined, callback: (...args: any[]) => void) {
const server = new net.Server();
function listen(port: number, hostname: string | undefined, callback: DetectPortCallback) {
const server = createServer();

server.on('error', err => {
server.once('error', err => {
debug('listen %s:%s error: %s', hostname, port, err);
server.close();

Expand All @@ -124,10 +124,11 @@ function listen(port: number, hostname: string | undefined, callback: (...args:
return callback(err);
});

debug('try listen %d on %s', port, hostname);
server.listen(port, hostname, () => {
port = (server.address() as net.AddressInfo).port;
server.close();
port = (server.address() as AddressInfo).port;
debug('get free %s:%s', hostname, port);
server.close();
return callback(null, port);
});
}
4 changes: 2 additions & 2 deletions src/wait-port.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { debuglog } from 'node:util';
import detectPort from './detect-port.js';

const debug = debuglog('wait-port');
const debug = debuglog('detect-port:wait-port');

const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));

Expand All @@ -15,7 +15,7 @@ export default async function waitPort(port: number, options: WaitPortOptions =
let count = 1;

async function loop() {
debug('retries', retries, 'count', count);
debug('wait port %d, retries %d, count %d', port, retries, count);
if (count > retries) {
const err = new Error('retries exceeded');
(err as any).retries = retries;
Expand Down
2 changes: 1 addition & 1 deletion test/cli.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const __dirname = path.dirname(__filename);
const pkgFile = path.join(__dirname, '../package.json');
const pkg = JSON.parse(readFileSync(pkgFile, 'utf-8'));

describe.skip('test/cli.test.js', async () => {
describe.skip('test/cli.test.ts', async () => {
const binFile = path.join(__dirname, '../bin/detect-port.cjs');

it('should show version', async () => {
Expand Down
96 changes: 49 additions & 47 deletions test/detect-port.test.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,43 @@
import dns from 'node:dns';
import net from 'node:net';
import { strict as assert } from 'node:assert';
import { mock, describe, it, before, after } from 'node:test';
import { ip } from 'address';
import mm from 'mm';

import detectPort from '../src/detect-port.js';

describe('test/detect-port.test.js', () => {
describe('test/detect-port.test.ts', () => {
afterEach(mm.restore);

describe('detect port test', () => {
const servers: net.Server[] = [];
before((_, done) => {
before(done => {
let count = 0;
const cb = mock.fn((err?: Error) => {
const cb = (err?: Error) => {
if (err) {
done(err);
}
count += 1;
if (count === 13) {
done();
}
});
};
const server = new net.Server();
server.listen(3000, 'localhost', cb);
server.listen(23000, 'localhost', cb);
server.on('error', err => {
console.error('listen localhost error:', err);
});
servers.push(server);

const server2 = new net.Server();
server2.listen(4000, ip(), cb);
server2.listen(24000, ip(), cb);
servers.push(server2);

const server3 = new net.Server();
server3.listen(8080, '0.0.0.0', cb);
server3.listen(28080, '0.0.0.0', cb);
servers.push(server3);

for (let port = 7000; port < 7010; port++) {
for (let port = 27000; port < 27010; port++) {
const server = new net.Server();
if (port % 3 === 0) {
server.listen(port, cb);
Expand All @@ -47,17 +49,17 @@ describe('test/detect-port.test.js', () => {
servers.push(server);
}
});

after(() => {
servers.forEach(server => server.close());
mock.reset();
});

it('get random port with callback', (_, done) => {
it('get random port with callback', done => {
detectPort((_, port) => {
assert(port);
assert(port >= 1024 && port < 65535);
done();
});

});

it('get random port with promise', async () => {
Expand All @@ -66,102 +68,102 @@ describe('test/detect-port.test.js', () => {
assert(port >= 1024 && port < 65535);
});

it('with occupied port', async () => {
it('with occupied port, like "listen EACCES: permission denied"', async () => {
const port = 80;
const realPort = await detectPort(port);

assert(realPort >= port && realPort < 65535);
});

it('work with listening next port 3001 because 3000 was listened to localhost', async () => {
const port = 3000;
it('work with listening next port 23001 because 23000 was listened to localhost', async () => {
const port = 23000;
const realPort = await detectPort(port);

assert(realPort === 3001);
assert(realPort);
assert.equal(realPort, 23001);
});

it('should listen next port 4001 when localhost is not binding', async t => {
t.mock.method(dns, 'lookup', (address: string, callback: (...args: any[]) => void) => {
it('should listen next port 24001 when localhost is not binding', async () => {
mm(dns, 'lookup', (...args: any[]) => {
mm.restore();
const address = args[0] as string;
if (address !== 'localhost') {
return dns.lookup(address, callback);
return dns.lookup(args[0], args[1], args[2]);
}
process.nextTick(() => {
const err = new Error(`getaddrinfo ENOTFOUND ${address}`);
(err as any).code = 'ENOTFOUND';
const callback = args[-1];
callback(err);
});
}, { times: 1 });
});

const port = 4000;
const port = 24000;
const realPort = await detectPort(port);

assert(realPort === 4001);

t.mock.reset();
assert.equal(realPort, 24001);
});

it('work with listening next port 4001 because 4000 was listened to ' + ip(), async () => {
const port = 4000;
it('work with listening next port 24001 because 24000 was listened to ' + ip(), async () => {
const port = 24000;
const realPort = await detectPort(port);

assert(realPort === 4001);
assert(realPort === 24001);
});

it('work with listening next port 8081 because 8080 was listened to 0.0.0.0:8080', async () => {
const port = 8080;
it('work with listening next port 28081 because 28080 was listened to 0.0.0.0:28080', async () => {
const port = 28080;
const realPort = await detectPort(port);

assert(realPort === 8081);
assert(realPort === 28081);
});

it('work with listening random port when try port hit maxPort', async () => {
const port = 7000;
const port = 27000;
const realPort = await detectPort(port);
assert(realPort < 7000 || realPort > 7009);
assert(realPort < 27000 || realPort > 27009);
});

it('work with sending object with hostname', (_, done) => {
const port = 7000;
it('work with sending object with hostname', done => {
const port = 27000;
const hostname = '127.0.0.1';
detectPort({
port,
hostname,
callback: (_, realPort) => {
assert(realPort >= 7000 && realPort < 65535);
assert(realPort);
assert(realPort >= 27000 && realPort < 65535);
done();
},
});
});

it('promise with sending object with hostname', async () => {
const port = 7000;
const port = 27000;
const hostname = '127.0.0.1';
const realPort = await detectPort({
port,
hostname,
});
assert(realPort >= 7000 && realPort < 65535);
assert(realPort >= 27000 && realPort < 65535);
});

it('with string arg', async () => {
const port = '8080';
const port = '28080';
const realPort = await detectPort(port);
assert(realPort >= 8080 && realPort < 65535);
assert(realPort >= 28080 && realPort < 65535);
});

it('with wrong arguments', async () => {
const port = await detectPort('oooo');
assert(port && port > 0);
});

it('generator usage', async () => {
const port = 8080;
it('async/await usage', async () => {
const port = 28080;
const realPort = await detectPort(port);
assert(realPort >= port && realPort < 65535);
});

it('promise usage', (_, done) => {
const _port = 8080;
it('promise usage', done => {
const _port = 28080;
detectPort(_port)
.then(port => {
assert(port >= _port && port < 65535);
Expand All @@ -170,7 +172,7 @@ describe('test/detect-port.test.js', () => {
.catch(done);
});

it('promise with wrong arguments', (_, done) => {
it('promise with wrong arguments', done => {
detectPort()
.then(port => {
assert(port > 0);
Expand Down
Loading

0 comments on commit 815eb45

Please sign in to comment.