add /api/tunnels/:id/status endpoint

Provides connected_sockets information for a tunnel.
This commit is contained in:
Roman Shtylman 2018-05-16 16:41:05 -04:00
parent 317db73bdc
commit cf070d4ce9
7 changed files with 89 additions and 11 deletions

View File

@ -12,6 +12,10 @@ class Client {
this.debug = Debug('lt:Client');
}
stats() {
return this.agent.stats();
}
handleRequest(req, res) {
this.debug('> %s', req.url);
const opt = {

View File

@ -39,6 +39,12 @@ class TunnelAgent extends Agent {
this.closed = false;
}
stats() {
return {
connectedSockets: this.connectedSockets,
};
}
listen() {
const server = this.server;
if (this.started) {

View File

@ -173,4 +173,11 @@ describe('TunnelAgent', () => {
});
assert.equal(err.message, 'foo');
});
it('should return stats', async () => {
const agent = new TunnelAgent();
assert.deepEqual(agent.stats(), {
connectedSockets: 0,
});
});
});

View File

@ -14,6 +14,7 @@
"esm": "3.0.34",
"human-readable-ids": "1.0.3",
"koa": "2.5.1",
"koa-router": "7.4.0",
"localenv": "0.2.2",
"optimist": "0.6.1",
"pump": "3.0.0",

View File

@ -4,6 +4,7 @@ import tldjs from 'tldjs';
import Debug from 'debug';
import http from 'http';
import { hri } from 'human-readable-ids';
import Router from 'koa-router';
import ClientManager from './lib/ClientManager';
@ -25,23 +26,33 @@ export default function(opt) {
const schema = opt.secure ? 'https' : 'http';
const app = new Koa();
const router = new Router();
// api status endpoint
app.use(async (ctx, next) => {
const path = ctx.request.path;
if (path !== '/api/status') {
await next();
return;
}
router.get('/api/status', async (ctx, next) => {
const stats = manager.stats;
ctx.body = {
tunnels: stats.tunnels,
mem: process.memoryUsage(),
};
});
router.get('/api/tunnels/:id/status', async (ctx, next) => {
const clientId = ctx.params.id;
const client = manager.getClient(clientId);
if (!client) {
ctx.throw(404);
return;
}
const stats = client.stats();
ctx.body = {
connected_sockets: stats.connectedSockets,
};
});
app.use(router.routes());
app.use(router.allowedMethods());
// root endpoint
app.use(async (ctx, next) => {
const path = ctx.request.path;

View File

@ -82,4 +82,28 @@ describe('Server', () => {
wss.close();
await new Promise(resolve => server.close(resolve));
});
it('should support the /api/tunnels/:id/status endpoint', async () => {
const server = createServer();
await new Promise(resolve => server.listen(resolve));
// no such tunnel yet
const res = await request(server).get('/api/tunnels/foobar-test/status');
assert.equal(res.statusCode, 404);
// request a new client called foobar-test
{
const res = await request(server).get('/foobar-test');
}
{
const res = await request(server).get('/api/tunnels/foobar-test/status');
assert.equal(res.statusCode, 200);
assert.deepEqual(res.body, {
connected_sockets: 0,
});
}
await new Promise(resolve => server.close(resolve));
});
});

View File

@ -348,7 +348,7 @@ http-assert@^1.1.0:
deep-equal "~1.0.1"
http-errors "~1.6.1"
http-errors@^1.2.8, http-errors@~1.6.1:
http-errors@^1.2.8, http-errors@^1.3.1, http-errors@~1.6.1:
version "1.6.3"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d"
dependencies:
@ -416,6 +416,10 @@ is@~0.2.6:
version "0.2.7"
resolved "https://registry.yarnpkg.com/is/-/is-0.2.7.tgz#3b34a2c48f359972f35042849193ae7264b63562"
isarray@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
@ -453,6 +457,17 @@ koa-is-json@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/koa-is-json/-/koa-is-json-1.0.0.tgz#273c07edcdcb8df6a2c1ab7d59ee76491451ec14"
koa-router@7.4.0:
version "7.4.0"
resolved "https://registry.yarnpkg.com/koa-router/-/koa-router-7.4.0.tgz#aee1f7adc02d5cb31d7d67465c9eacc825e8c5e0"
dependencies:
debug "^3.1.0"
http-errors "^1.3.1"
koa-compose "^3.0.0"
methods "^1.0.1"
path-to-regexp "^1.1.1"
urijs "^1.19.0"
koa@2.5.1:
version "2.5.1"
resolved "https://registry.yarnpkg.com/koa/-/koa-2.5.1.tgz#79f8b95f8d72d04fe9a58a8da5ebd6d341103f9c"
@ -615,7 +630,7 @@ meow@^3.3.0:
redent "^1.0.0"
trim-newlines "^1.0.0"
methods@^1.1.1, methods@~1.1.2:
methods@^1.0.1, methods@^1.1.1, methods@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
@ -782,6 +797,12 @@ path-parse@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1"
path-to-regexp@^1.1.1:
version "1.7.0"
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d"
dependencies:
isarray "0.0.1"
path-type@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441"
@ -998,6 +1019,10 @@ type-is@^1.5.5:
media-typer "0.3.0"
mime-types "~2.1.18"
urijs@^1.19.0:
version "1.19.1"
resolved "https://registry.yarnpkg.com/urijs/-/urijs-1.19.1.tgz#5b0ff530c0cbde8386f6342235ba5ca6e995d25a"
util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"