Implement rammerhead proxy.

This commit is contained in:
wearrrrr 2024-02-07 14:00:37 -06:00
parent 31c7f410c8
commit 46040b28df
6 changed files with 1683 additions and 66 deletions

View file

@ -1,19 +1,79 @@
import { createBareServer } from "@tomphttp/bare-server-node";
import { uvPath } from "@nebula-services/ultraviolet"; import { uvPath } from "@nebula-services/ultraviolet";
import http from "node:http"; import { createBareServer } from "@tomphttp/bare-server-node";
import path from "node:path";
import express from "express"; import express from "express";
import { handler as ssrHandler } from "./dist/server/entry.mjs"; import { createServer } from "http";
import dotenv from "dotenv"; import path from "node:path";
import createRammerhead from "rammerhead/src/server/index.js";
import compression from "compression"; import compression from "compression";
import { build } from "astro";
import chalk from "chalk"; import chalk from "chalk";
import { existsSync } from "fs";
import dotenv from "dotenv";
dotenv.config(); dotenv.config();
if (!existsSync("./dist")) build();
const PORT = process.env.PORT || 3000; const PORT = process.env.PORT || 3000;
const server = http.createServer(); const bare = createBareServer("/bare/");
const app = express(server);
const bareServer = createBareServer("/bare/"); const rh = createRammerhead();
const rammerheadScopes = [
"/rammerhead.js",
"/hammerhead.js",
"/transport-worker.js",
"/task.js",
"/iframe-task.js",
"/worker-hammerhead.js",
"/messaging",
"/sessionexists",
"/deletesession",
"/newsession",
"/editsession",
"/needpassword",
"/syncLocalStorage",
"/api/shuffleDict",
"/mainport",
];
const rammerheadSession = /^\/[a-z0-9]{32}/;
function shouldRouteRh(req) {
const url = new URL(req.url, "http://0.0.0.0");
return rammerheadScopes.includes(url.pathname) || rammerheadSession.test(url.pathname);
}
function routeRhRequest(req, res) {
rh.emit("request", req, res);
}
function routeRhUpgrade(req, socket, head) {
rh.emit("upgrade", req, socket, head);
}
let server = createServer();
server.on("request", (req, res) => {
if (bare.shouldRoute(req)) {
bare.routeRequest(req, res);
} else if (shouldRouteRh(req)) {
routeRhRequest(req, res);
} else {
app(req, res);
}
});
server.on("upgrade", (req, socket, head) => {
if (bare.shouldRoute(req)) {
bare.routeUpgrade(req, socket, head);
} else if (shouldRouteRh(req)) {
routeRhUpgrade(req, socket, head);
} else {
socket.end();
}
});
const app = express();
app.use(compression()); app.use(compression());
app.use(express.static(path.join(process.cwd(), "static"))); app.use(express.static(path.join(process.cwd(), "static")));
app.use(express.static(path.join(process.cwd(), "build"))); app.use(express.static(path.join(process.cwd(), "build")));
@ -25,27 +85,6 @@ app.use(
}) })
); );
app.use("/", express.static("dist/client/")); app.use("/", express.static("dist/client/"));
app.use(ssrHandler);
app.get("*", function (req, res) {
res.status(200).sendFile("404.html", { root: path.resolve("dist/client") });
});
server.on("request", (req, res) => {
if (bareServer.shouldRoute(req)) {
bareServer.routeRequest(req, res);
} else {
app(req, res);
}
});
server.on("upgrade", (req, socket, head) => {
if (bareServer.shouldRoute(req)) {
bareServer.routeUpgrade(req, socket, head);
} else {
socket.end();
}
});
console.log(chalk.gray("Starting Alu...")); console.log(chalk.gray("Starting Alu..."));
server.on("listening", () => { server.on("listening", () => {

58
index.js.bak Normal file
View file

@ -0,0 +1,58 @@
import { createBareServer } from "@tomphttp/bare-server-node";
import { uvPath } from "@nebula-services/ultraviolet";
import http from "node:http";
import path from "node:path";
import express from "express";
import { handler as ssrHandler } from "./dist/server/entry.mjs";
import dotenv from "dotenv";
import compression from "compression";
import createRammerhead from "rammerhead/src/server/index.js";
import chalk from "chalk";
dotenv.config();
const PORT = process.env.PORT || 3000;
const server = http.createServer();
const app = express(server);
const bareServer = createBareServer("/bare/");
app.use(compression());
app.use(express.static(path.join(process.cwd(), "static")));
app.use(express.static(path.join(process.cwd(), "build")));
app.use("/uv/", express.static(uvPath));
app.use(express.json());
app.use(
express.urlencoded({
extended: true,
})
);
app.use("/", express.static("dist/client/"));
app.use(ssrHandler);
app.get("*", function (req, res) {
res.status(200).sendFile("404.html", { root: path.resolve("dist/client") });
});
server.on('request', (req, res) => {
if (bareServer.shouldRoute(req)) {
bareServer.routeRequest(req, res);
} else {
app(req, res);
}
});
server.on('upgrade', (req, socket, head) => {
if (bareServer.shouldRoute(req)) {
bareServer.routeUpgrade(req, socket, head);
} else {
socket.end();
}
});
console.log(chalk.gray("Starting Alu..."));
server.on("listening", () => {
console.log(chalk.green(`Server running at http://localhost:${PORT}/.`));
});
server.listen({
port: PORT,
});

1542
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -19,11 +19,14 @@
"chalk": "^5.3.0", "chalk": "^5.3.0",
"compression": "^1.7.4", "compression": "^1.7.4",
"dotenv": "^16.3.1", "dotenv": "^16.3.1",
"dotenv-flow": "^4.1.0",
"express": "^4.18.2", "express": "^4.18.2",
"i": "^0.3.7", "i": "^0.3.7",
"i18next": "^23.7.18", "i18next": "^23.7.18",
"i18next-browser-languagedetector": "^7.2.0", "i18next-browser-languagedetector": "^7.2.0",
"npm": "^10.2.5", "npm": "^10.2.5",
"path": "^0.12.7",
"rammerhead": "https://github.com/holy-unblocker/rammerhead/releases/download/v1.2.41-holy.5/rammerhead-1.2.41-holy.5.tgz",
"typescript": "^5.3.3" "typescript": "^5.3.3"
}, },
"devDependencies": { "devDependencies": {

View file

@ -17,7 +17,7 @@
form.addEventListener("submit", formEventListener); form.addEventListener("submit", formEventListener);
} }
function formEventListener(event) { async function formEventListener(event) {
event.preventDefault(); event.preventDefault();
let loadingContent = document.getElementById("loading-content"); let loadingContent = document.getElementById("loading-content");
loadingContent.style.opacity = 1; loadingContent.style.opacity = 1;
@ -26,7 +26,24 @@
else if (!(url.startsWith("https://") || url.startsWith("http://"))) url = "http://" + url; else if (!(url.startsWith("https://") || url.startsWith("http://"))) url = "http://" + url;
let iframe = document.getElementById("proxy-frame"); let iframe = document.getElementById("proxy-frame");
iframe.src = window.__uv$config.prefix + window.__uv$config.encodeUrl(url); let preference = getProxyPreference();
if (preference === "ultraviolet") {
iframe.src = window.__uv$config.prefix + window.__uv$config.encodeUrl(url);
} else if (preference == "rammerhead") {
// Check if rammerhead-session exists in cookies
let rammerheadSession = getCookie("rammerhead-session");
console.log(rammerheadSession);
if (!rammerheadSession) {
let session = await fetch("/newsession");
let sessionID = await session.text();
// Now save it in a cookie that expires in 72 hours.
document.cookie = `rammerhead-session=${sessionID}; max-age=${60 * 60 * 72}; path=/`;
}
iframe.src = `/${getCookie("rammerhead-session")}/${url}`;
} else {
// Default to UV
iframe.src = window.__uv$config.prefix + window.__uv$config.encodeUrl(url);
}
iframe.style.pointerEvents = "auto"; iframe.style.pointerEvents = "auto";
iframe.classList.add("proxy-frame"); iframe.classList.add("proxy-frame");
document.body.appendChild(iframe); document.body.appendChild(iframe);
@ -61,6 +78,12 @@
return false; return false;
} }
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(";").shift();
}
function getSearchEngine() { function getSearchEngine() {
let localStorageSearchEngine = localStorage.getItem("alu__search_engine"); let localStorageSearchEngine = localStorage.getItem("alu__search_engine");
if (!localStorageSearchEngine) { if (!localStorageSearchEngine) {
@ -90,4 +113,24 @@
} }
} }
} }
function getProxyPreference() {
let localStorageItem = localStorage.getItem("alu__selectedProxy");
if (!localStorageItem) return "uv";
switch (JSON.parse(localStorageItem).value.toLowerCase()) {
case "ultraviolet": {
return "ultraviolet";
}
case "rammerhead":
return "rammerhead";
case "dynamic":
// temporary because dynamic is not implemented yet :)
return "ultraviolet";
default: {
return "uv";
}
}
}
</script> </script>

View file

@ -5,7 +5,7 @@ import Footer from "../components/Footer.astro";
import ThemeLoader from "../components/ThemeLoader.astro"; import ThemeLoader from "../components/ThemeLoader.astro";
import CloakLoader from "../components/CloakLoader.astro"; import CloakLoader from "../components/CloakLoader.astro";
import WelcomeLogging from "../components/WelcomeLogging.astro"; import WelcomeLogging from "../components/WelcomeLogging.astro";
import UVRegistrar from "../components/UVRegistrar.astro"; import UVRegistrar from "../components/ProxyRegistrar.astro";
type Preload = { type Preload = {
href: string; href: string;