api: move itunnel handlers to separate file

This commit is contained in:
jj 2024-12-16 10:38:31 +00:00
parent f06aa65801
commit bc597c817f
No known key found for this signature in database
2 changed files with 67 additions and 37 deletions

View file

@ -8,18 +8,19 @@ import jwt from "../security/jwt.js";
import stream from "../stream/stream.js"; import stream from "../stream/stream.js";
import match from "../processing/match.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 { 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 { hashHmac } from "../security/secrets.js";
import { createStore } from "../store/redis-ratelimit.js"; import { createStore } from "../store/redis-ratelimit.js";
import { randomizeCiphers } from "../misc/randomize-ciphers.js"; import { randomizeCiphers } from "../misc/randomize-ciphers.js";
import { verifyTurnstileToken } from "../security/turnstile.js"; import { verifyTurnstileToken } from "../security/turnstile.js";
import { friendlyServiceName } from "../processing/service-alias.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 { createResponse, normalizeRequest, getIP } from "../processing/request.js";
import * as APIKeys from "../security/api-keys.js"; import * as APIKeys from "../security/api-keys.js";
import * as Cookies from "../processing/cookie/manager.js"; import * as Cookies from "../processing/cookie/manager.js";
import { setupTunnelHandler } from "./itunnel.js";
const git = { const git = {
branch: await getBranch(), branch: await getBranch(),
@ -292,29 +293,7 @@ export const runAPI = async (express, app, __dirname, isPrimary = true) => {
} }
return stream(res, streamInfo); 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) => { app.get('/', (_, res) => {
res.type('json'); res.type('json');
@ -376,15 +355,5 @@ export const runAPI = async (express, app, __dirname, isPrimary = true) => {
} }
}); });
const istreamer = express(); setupTunnelHandler();
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);
});
} }

61
api/src/core/itunnel.js Normal file
View file

@ -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);
});
}