Skip to content

Commit

Permalink
refactor: http listener
Browse files Browse the repository at this point in the history
- Convert to typescript
- Add unit test
  • Loading branch information
fredriklindberg committed Oct 30, 2023
1 parent da958a8 commit 0bb6986
Show file tree
Hide file tree
Showing 13 changed files with 697 additions and 375 deletions.
12 changes: 4 additions & 8 deletions src/controller/admin-api-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class AdminApiController extends KoaController {
}
}

protected _initializeRoutes(router: Router.Router) {
protected _initializeRoutes(router: Router.Router): void {

const handleError: Router.FullHandler = async (ctx, next) => {
if (!ctx.invalid) {
Expand Down Expand Up @@ -122,7 +122,7 @@ class AdminApiController extends KoaController {
}
};

const tunnelProps = (tunnel: Tunnel, baseUrl: string) => {
const tunnelProps = (tunnel: Tunnel, baseUrl: URL | undefined) => {
return {
tunnel_id: tunnel.id,
account_id: tunnel.account,
Expand Down Expand Up @@ -154,10 +154,6 @@ class AdminApiController extends KoaController {
}
};

const getBaseUrl = (req: any) => {
return req._exposrBaseUrl;
}

router.route({
method: 'post',
path: '/v1/admin/account',
Expand Down Expand Up @@ -276,7 +272,7 @@ class AdminApiController extends KoaController {
try {
const tunnel = await this._tunnelService.lookup(ctx.params.tunnel_id);
ctx.status = 200;
ctx.body = tunnelProps(tunnel, getBaseUrl(ctx.req));
ctx.body = tunnelProps(tunnel, this.getBaseUrl(ctx.req));
} catch (e: any) {
if (e.message == 'no_such_tunnel') {
ctx.status = 404;
Expand Down Expand Up @@ -370,7 +366,7 @@ class AdminApiController extends KoaController {
ctx.body = {
cursor: res.cursor,
tunnels: res.tunnels.map((t) => {
return ctx.query.verbose ? tunnelProps(t, getBaseUrl(ctx.req)) : t.id;
return ctx.query.verbose ? tunnelProps(t, this.getBaseUrl(ctx.req)) : t.id;
}),
};
}]
Expand Down
12 changes: 4 additions & 8 deletions src/controller/api-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class ApiController extends KoaController {
}
}

_initializeRoutes(router: Router.Router) {
protected _initializeRoutes(router: Router.Router): void {

const handleError: Router.FullHandler = async (ctx, next) => {
if (!ctx.invalid) {
Expand Down Expand Up @@ -98,7 +98,7 @@ class ApiController extends KoaController {
return next();
};

const tunnelInfo = (tunnel: Tunnel, baseUrl: string) => {
const tunnelInfo = (tunnel: Tunnel, baseUrl: URL | undefined) => {
const info = {
id: tunnel.id,
connection: {
Expand Down Expand Up @@ -131,10 +131,6 @@ class ApiController extends KoaController {
return info;
};

const getBaseUrl = (req: any) => {
return req._exposrBaseUrl;
};

router.route({
method: ['put', 'patch'],
path: '/v1/tunnel/:tunnel_id',
Expand Down Expand Up @@ -209,7 +205,7 @@ class ApiController extends KoaController {
tunnel.transport.ssh.enabled =
body?.transport?.ssh?.enabled ?? tunnel.transport.ssh.enabled;
});
ctx.body = tunnelInfo(updatedTunnel, getBaseUrl(ctx.req));
ctx.body = tunnelInfo(updatedTunnel, this.getBaseUrl(ctx.req));
ctx.status = 200;
} catch (e: any) {
if (e.message == 'permission_denied') {
Expand Down Expand Up @@ -278,7 +274,7 @@ class ApiController extends KoaController {
try {
const tunnel = await this.tunnelService.get(tunnelId, account.id);
ctx.status = 200;
ctx.body = tunnelInfo(tunnel, getBaseUrl(ctx.req));
ctx.body = tunnelInfo(tunnel, this.getBaseUrl(ctx.req));
} catch (e: any) {
ctx.status = 404;
ctx.body = {
Expand Down
40 changes: 19 additions & 21 deletions src/controller/koa-controller.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
import { strict as assert } from 'assert';
import Koa from 'koa';
import Router, { FullHandler } from 'koa-joi-router';
import Listener from '../listener/index.js';
import HttpListener from '../listener/http-listener.js';
import Router from 'koa-joi-router';
import Listener from '../listener/listener.js';
import HttpListener, { HttpRequestCallback, HttpRequestType } from '../listener/http-listener.js';
import { IncomingMessage, ServerResponse } from 'http';

abstract class KoaController {

public readonly _name: string = 'controller'
private _port!: number;
private httpListener!: HttpListener;
private _requestHandler: any;
private _requestHandler!: HttpRequestCallback;
private router!: Router.Router;
private app!: Koa;

constructor(opts: any) {
if (opts == undefined) {
return;
}
assert(opts != undefined);
const {port, callback, logger, host, prio} = opts;

if (opts?.enable === false) {
Expand All @@ -26,8 +25,8 @@ abstract class KoaController {

this._port = port;

const useCallback: FullHandler = async (ctx, next) => {
const setBaseUrl = (req: any, baseUrl: string) => {
const useCallback: HttpRequestCallback = this._requestHandler = async (ctx, next) => {
const setBaseUrl = (req: any, baseUrl: URL | undefined) => {
req._exposrBaseUrl = baseUrl;
};
setBaseUrl(ctx.req, ctx.baseUrl)
Expand All @@ -36,15 +35,10 @@ abstract class KoaController {
}
}

const httpListener = this.httpListener = Listener.acquire('http', port, { app: new Koa() });
this._requestHandler = httpListener.use('request', { host, logger, prio, logBody: true }, useCallback);

httpListener.setState({
app: new Koa(),
...httpListener.state,
});
this.app = httpListener.state.app;
const httpListener = this.httpListener = Listener.acquire(HttpListener, port);
httpListener.use(HttpRequestType.request, { host, logger, prio, logBody: true }, useCallback);

this.app = new Koa();
this.router = Router();
this._initializeRoutes(this.router);
this.app.use(this.router.middleware());
Expand Down Expand Up @@ -73,13 +67,17 @@ abstract class KoaController {

protected abstract _destroy(): Promise<void>;

public async destroy() {
this.httpListener.removeHandler('request', this._requestHandler);
return Promise.allSettled([
Listener.release('http', this._port),
public async destroy(): Promise<void> {
this.httpListener?.removeHandler(HttpRequestType.request, this._requestHandler);
await Promise.allSettled([
Listener.release(this._port),
this._destroy(),
]);
}

protected getBaseUrl(req: IncomingMessage): URL | undefined {
return ((req as any)._exposrBaseUrl as (URL | undefined));
}
}

export default KoaController;
23 changes: 14 additions & 9 deletions src/ingress/http-ingress.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import http, { Agent } from 'http';
import net from 'net';
import NodeCache from 'node-cache';
import EventBus from '../cluster/eventbus.js';
import Listener from '../listener/index.js';
import Listener from '../listener/listener.js';
import IngressUtils from './utils.js';
import { Logger } from '../logger.js';
import TunnelService from '../tunnel/tunnel-service.js';
Expand All @@ -28,6 +28,7 @@ import {
HTTP_HEADER_X_FORWARDED_PROTO,
HTTP_HEADER_FORWARDED
} from '../utils/http-headers.js';
import HttpListener, { HttpRequestType } from '../listener/http-listener.js';

class HttpIngress {

Expand All @@ -45,17 +46,21 @@ class HttpIngress {
this.altNameService = new AltNameService();
this.tunnelService = opts.tunnelService;
assert(this.tunnelService instanceof TunnelService);
this.httpListener = Listener.acquire('http', opts.port);
this._requestHandler = this.httpListener.use('request', { logger: this.logger, prio: 1 }, async (ctx, next) => {
this.httpListener = Listener.acquire(HttpListener, opts.port);

this._requestHandler = async (ctx, next) => {
if (!await this.handleRequest(ctx.req, ctx.res, ctx.baseUrl)) {
next();
}
});
this._upgradeHandler = this.httpListener.use('upgrade', { logger: this.logger }, async (ctx, next) => {
};
this.httpListener.use(HttpRequestType.request, { logger: this.logger, prio: 1 }, this._requestHandler);

this._upgradeHandler = async (ctx, next) => {
if (!await this.handleUpgradeRequest(ctx.req, ctx.sock, ctx.head, ctx.baseUrl)) {
next();
}
});
};
this.httpListener.use(HttpRequestType.upgrade, { logger: this.logger }, this._upgradeHandler);

this._agentCache = new NodeCache({
useClones: false,
Expand Down Expand Up @@ -467,12 +472,12 @@ class HttpIngress {
return;
}
this.destroyed = true;
this.httpListener.removeHandler('request', this._requestHandler);
this.httpListener.removeHandler('upgrade', this._upgradeHandler);
this.httpListener.removeHandler(HttpRequestType.request, this._requestHandler);
this.httpListener.removeHandler(HttpRequestType.upgrade, this._upgradeHandler);
return Promise.allSettled([
this.altNameService.destroy(),
this.eventBus.destroy(),
Listener.release('http', this.opts.port),
Listener.release(this.opts.port),
]);
}

Expand Down
Loading

0 comments on commit 0bb6986

Please sign in to comment.