2024-04-14 09:51:00 +02:00
|
|
|
import { errorResponse, response } from "@response";
|
2024-04-07 07:30:49 +02:00
|
|
|
import type { Config } from "config-manager";
|
2024-03-11 03:04:14 +01:00
|
|
|
import { matches } from "ip-matching";
|
|
|
|
|
import type { LogManager, MultiLogManager } from "log-manager";
|
|
|
|
|
import { LogLevel } from "log-manager";
|
2024-04-14 10:16:03 +02:00
|
|
|
import { processRoute } from "server-handler";
|
2024-03-13 09:10:32 +01:00
|
|
|
import { matchRoute } from "~routes";
|
2024-03-11 03:04:14 +01:00
|
|
|
|
|
|
|
|
export const createServer = (
|
2024-04-07 07:30:49 +02:00
|
|
|
config: Config,
|
|
|
|
|
logger: LogManager | MultiLogManager,
|
|
|
|
|
isProd: boolean,
|
2024-03-11 03:04:14 +01:00
|
|
|
) =>
|
2024-04-07 07:30:49 +02:00
|
|
|
Bun.serve({
|
|
|
|
|
port: config.http.bind_port,
|
|
|
|
|
hostname: config.http.bind || "0.0.0.0", // defaults to "0.0.0.0"
|
|
|
|
|
async fetch(req) {
|
|
|
|
|
// Check for banned IPs
|
|
|
|
|
const request_ip = this.requestIP(req)?.address ?? "";
|
|
|
|
|
|
|
|
|
|
for (const ip of config.http.banned_ips) {
|
|
|
|
|
try {
|
|
|
|
|
if (matches(ip, request_ip)) {
|
2024-04-08 05:28:18 +02:00
|
|
|
return errorResponse("Forbidden", 403);
|
2024-04-07 07:30:49 +02:00
|
|
|
}
|
|
|
|
|
} catch (e) {
|
2024-04-14 13:20:55 +02:00
|
|
|
logger.log(
|
|
|
|
|
LogLevel.ERROR,
|
|
|
|
|
"Server.IPCheck",
|
|
|
|
|
`Error while parsing banned IP "${ip}" `,
|
|
|
|
|
);
|
|
|
|
|
logger.logError(
|
|
|
|
|
LogLevel.ERROR,
|
|
|
|
|
"Server.IPCheck",
|
|
|
|
|
e as Error,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return errorResponse(
|
|
|
|
|
`A server error occured: ${(e as Error).message}`,
|
|
|
|
|
500,
|
|
|
|
|
);
|
2024-04-07 07:30:49 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check for banned user agents (regex)
|
|
|
|
|
const ua = req.headers.get("User-Agent") ?? "";
|
|
|
|
|
|
|
|
|
|
for (const agent of config.http.banned_user_agents) {
|
|
|
|
|
if (new RegExp(agent).test(ua)) {
|
2024-04-08 05:28:18 +02:00
|
|
|
return errorResponse("Forbidden", 403);
|
2024-04-07 07:30:49 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (config.http.bait.enabled) {
|
|
|
|
|
// Check for bait IPs
|
|
|
|
|
for (const ip of config.http.bait.bait_ips) {
|
|
|
|
|
try {
|
|
|
|
|
if (matches(ip, request_ip)) {
|
|
|
|
|
const file = Bun.file(
|
2024-04-09 13:14:53 +02:00
|
|
|
config.http.bait.send_file || "./beemovie.txt",
|
2024-04-07 07:30:49 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (await file.exists()) {
|
2024-04-08 05:28:18 +02:00
|
|
|
return response(file);
|
2024-04-07 07:30:49 +02:00
|
|
|
}
|
|
|
|
|
await logger.log(
|
|
|
|
|
LogLevel.ERROR,
|
|
|
|
|
"Server.Bait",
|
|
|
|
|
`Bait file not found: ${config.http.bait.send_file}`,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
2024-04-14 13:20:55 +02:00
|
|
|
logger.log(
|
|
|
|
|
LogLevel.ERROR,
|
|
|
|
|
"Server.IPCheck",
|
|
|
|
|
`Error while parsing bait IP "${ip}" `,
|
|
|
|
|
);
|
|
|
|
|
logger.logError(
|
|
|
|
|
LogLevel.ERROR,
|
|
|
|
|
"Server.IPCheck",
|
|
|
|
|
e as Error,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return errorResponse(
|
|
|
|
|
`A server error occured: ${(e as Error).message}`,
|
|
|
|
|
500,
|
2024-04-07 07:30:49 +02:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check for bait user agents (regex)
|
|
|
|
|
for (const agent of config.http.bait.bait_user_agents) {
|
|
|
|
|
if (new RegExp(agent).test(ua)) {
|
|
|
|
|
const file = Bun.file(
|
2024-04-09 13:14:53 +02:00
|
|
|
config.http.bait.send_file || "./beemovie.txt",
|
2024-04-07 07:30:49 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (await file.exists()) {
|
2024-04-08 05:28:18 +02:00
|
|
|
return response(file);
|
2024-04-07 07:30:49 +02:00
|
|
|
}
|
|
|
|
|
await logger.log(
|
|
|
|
|
LogLevel.ERROR,
|
|
|
|
|
"Server.Bait",
|
|
|
|
|
`Bait file not found: ${config.http.bait.send_file}`,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (config.logging.log_requests) {
|
|
|
|
|
await logger.logRequest(
|
2024-04-07 14:26:19 +02:00
|
|
|
req.clone(),
|
2024-04-07 07:30:49 +02:00
|
|
|
config.logging.log_ip ? request_ip : undefined,
|
|
|
|
|
config.logging.log_requests_verbose,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-10 05:45:19 +02:00
|
|
|
// If route is .well-known, remove dot because the filesystem router can't handle dots for some reason
|
2024-04-14 13:57:26 +02:00
|
|
|
const matchedRoute = matchRoute(
|
2024-04-10 05:45:19 +02:00
|
|
|
req.url.replace(".well-known", "well-known"),
|
2024-04-07 07:30:49 +02:00
|
|
|
);
|
|
|
|
|
|
2024-04-14 13:57:26 +02:00
|
|
|
console.log(matchedRoute);
|
|
|
|
|
|
2024-04-14 13:52:50 +02:00
|
|
|
if (
|
|
|
|
|
matchedRoute &&
|
|
|
|
|
Object.keys(matchedRoute).length !== 0 &&
|
|
|
|
|
matchedRoute.name !== "/[...404]"
|
|
|
|
|
) {
|
2024-04-14 09:51:00 +02:00
|
|
|
return await processRoute(matchedRoute, req, logger);
|
2024-04-09 06:33:59 +02:00
|
|
|
}
|
|
|
|
|
|
2024-04-09 13:42:53 +02:00
|
|
|
const base_url_with_http = config.http.base_url.replace(
|
|
|
|
|
"https://",
|
|
|
|
|
"http://",
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const replacedUrl = req.url
|
|
|
|
|
.replace(config.http.base_url, "http://localhost:5173")
|
|
|
|
|
.replace(base_url_with_http, "http://localhost:5173");
|
|
|
|
|
|
2024-04-14 07:26:29 +02:00
|
|
|
const proxy = await fetch(replacedUrl, {
|
|
|
|
|
headers: {
|
|
|
|
|
// Include for SSR
|
|
|
|
|
"X-Forwarded-Host": `${config.http.bind}:${config.http.bind_port}`,
|
|
|
|
|
},
|
|
|
|
|
}).catch(async (e) => {
|
2024-04-09 06:33:59 +02:00
|
|
|
await logger.logError(
|
|
|
|
|
LogLevel.ERROR,
|
|
|
|
|
"Server.Proxy",
|
|
|
|
|
e as Error,
|
|
|
|
|
);
|
|
|
|
|
await logger.log(
|
|
|
|
|
LogLevel.ERROR,
|
|
|
|
|
"Server.Proxy",
|
2024-04-09 13:42:53 +02:00
|
|
|
`The development Vite server is not running or the route is not found: ${replacedUrl}`,
|
2024-04-09 06:33:59 +02:00
|
|
|
);
|
2024-04-07 07:30:49 +02:00
|
|
|
return errorResponse("Route not found", 404);
|
2024-04-09 06:33:59 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
proxy.status !== 404 &&
|
|
|
|
|
!(await proxy.clone().text()).includes("404 Not Found")
|
|
|
|
|
) {
|
|
|
|
|
return proxy;
|
2024-04-07 07:30:49 +02:00
|
|
|
}
|
2024-04-09 06:33:59 +02:00
|
|
|
|
2024-04-07 07:30:49 +02:00
|
|
|
return errorResponse("Route not found", 404);
|
|
|
|
|
},
|
|
|
|
|
});
|