From bc597c817faa2dec9ce386458dac4f7a8cdb6b48 Mon Sep 17 00:00:00 2001 From: jj Date: Mon, 16 Dec 2024 10:38:31 +0000 Subject: [PATCH] api: move itunnel handlers to separate file --- api/src/core/api.js | 43 ++++------------------------- api/src/core/itunnel.js | 61 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 37 deletions(-) create mode 100644 api/src/core/itunnel.js diff --git a/api/src/core/api.js b/api/src/core/api.js index e19e0674..b93ff2ca 100644 --- a/api/src/core/api.js +++ b/api/src/core/api.js @@ -8,18 +8,19 @@ import jwt from "../security/jwt.js"; import stream from "../stream/stream.js"; import match from "../processing/match.js"; -import { env, isCluster, setTunnelPort } from "../config.js"; +import { env } from "../config.js"; import { extract } from "../processing/url.js"; -import { Green, Bright, Cyan } from "../misc/console-text.js"; +import { Bright, Cyan } from "../misc/console-text.js"; import { hashHmac } from "../security/secrets.js"; import { createStore } from "../store/redis-ratelimit.js"; import { randomizeCiphers } from "../misc/randomize-ciphers.js"; import { verifyTurnstileToken } from "../security/turnstile.js"; import { friendlyServiceName } from "../processing/service-alias.js"; -import { verifyStream, getInternalTunnel } from "../stream/manage.js"; +import { verifyStream } from "../stream/manage.js"; import { createResponse, normalizeRequest, getIP } from "../processing/request.js"; import * as APIKeys from "../security/api-keys.js"; import * as Cookies from "../processing/cookie/manager.js"; +import { setupTunnelHandler } from "./itunnel.js"; const git = { branch: await getBranch(), @@ -292,29 +293,7 @@ export const runAPI = async (express, app, __dirname, isPrimary = true) => { } return stream(res, streamInfo); - }) - - const itunnelHandler = (req, res) => { - if (!req.ip.endsWith('127.0.0.1')) { - return res.sendStatus(403); - } - - if (String(req.query.id).length !== 21) { - return res.sendStatus(400); - } - - const streamInfo = getInternalTunnel(req.query.id); - if (!streamInfo) { - return res.sendStatus(404); - } - - streamInfo.headers = new Map([ - ...(streamInfo.headers || []), - ...Object.entries(req.headers) - ]); - - return stream(res, { type: 'internal', ...streamInfo }); - }; + }); app.get('/', (_, res) => { res.type('json'); @@ -376,15 +355,5 @@ export const runAPI = async (express, app, __dirname, isPrimary = true) => { } }); - const istreamer = express(); - istreamer.get('/itunnel', itunnelHandler); - const server = istreamer.listen({ - port: 0, - host: '127.0.0.1', - exclusive: true - }, () => { - const { port } = server.address(); - console.log(`${Green('[✓]')} cobalt sub-instance running on 127.0.0.1:${port}`); - setTunnelPort(port); - }); + setupTunnelHandler(); } diff --git a/api/src/core/itunnel.js b/api/src/core/itunnel.js new file mode 100644 index 00000000..fea4cb76 --- /dev/null +++ b/api/src/core/itunnel.js @@ -0,0 +1,61 @@ +import stream from "../stream/stream.js"; +import { getInternalTunnel } from "../stream/manage.js"; +import { setTunnelPort } from "../config.js"; +import { Green } from "../misc/console-text.js"; +import express from "express"; + +const validateTunnel = (req, res) => { + if (!req.ip.endsWith('127.0.0.1')) { + res.sendStatus(403); + return; + } + + if (String(req.query.id).length !== 21) { + res.sendStatus(400); + return; + } + + const streamInfo = getInternalTunnel(req.query.id); + if (!streamInfo) { + res.sendStatus(404); + return; + } + + return streamInfo; +} + +const streamTunnel = (req, res) => { + const streamInfo = validateTunnel(req, res); + if (!streamInfo) { + return; + } + + streamInfo.headers = new Map([ + ...(streamInfo.headers || []), + ...Object.entries(req.headers) + ]); + + return stream(res, { type: 'internal', ...streamInfo }); +} + +export const setupTunnelHandler = () => { + const tunnelHandler = express(); + + tunnelHandler.get('/itunnel', streamTunnel); + + // fallback + tunnelHandler.use((_, res) => res.sendStatus(400)); + // error handler + tunnelHandler.use((_, __, res, ____) => res.socket.end()); + + + const server = tunnelHandler.listen({ + port: 0, + host: '127.0.0.1', + exclusive: true + }, () => { + const { port } = server.address(); + console.log(`${Green('[✓]')} internal tunnel handler running on 127.0.0.1:${port}`); + setTunnelPort(port); + }); +}