Spaces:
Running
Running
const http = require('http'); | |
const { spawn } = require('child_process'); | |
const PROXY_PORT_HUGGINGFACE = 4444; // Change this to a port different from 1688 | |
const PROXY_PORT_OMNITOOL = 1689; // Change this to a port different from 1688 | |
const CONTAINER_HOST = '127.0.0.1'; | |
const CONTAINER_PORT_OMNITOOL = 1688; | |
const PROTOCOL = 'https'; | |
let OMNITOOL_READY = false; | |
let OMNITOOL_PRE_READY = false; | |
let ALREADY_STARTING = false; | |
const VERSION = '0.0.5'; | |
console.log(`************ Omnitool Proxy Server v${VERSION} ************`); | |
let omnitoolLogs = []; | |
async function startOmnitoolServer() | |
{ | |
if (ALREADY_STARTING) return; | |
ALREADY_STARTING = true; | |
console.log('Starting Omnitool Server...'); | |
return new Promise((resolve, reject) => | |
{ | |
const omnitoolStartProcess = spawn('./omnitool_start.sh'); | |
omnitoolStartProcess.stdout.on('data', (data) => | |
{ | |
omnitoolLogs.push(data.toString()); | |
console.log(`omnitool stdout: ${data}`); | |
if (data.toString().includes(`Server has started and is ready to accept connections`)) | |
{ | |
console.log('Omnitool server started successfully'); | |
OMNITOOL_PRE_READY = true; | |
setTimeout(() => | |
{ | |
OMNITOOL_READY = true; | |
resolve(); | |
}, 1000); // Delay by 1 second | |
} | |
}); | |
omnitoolStartProcess.stderr.on('data', (data) => | |
{ | |
console.error(`omnitool stderr: ${data}`); | |
omnitoolLogs.push(data.toString()); | |
}); | |
omnitoolStartProcess.on('close', (code) => | |
{ | |
const message = `Omnitool server process exited with code: ${code}`; | |
console.log(message); | |
omnitoolLogs.push(message); | |
if (!OMNITOOL_READY) | |
{ | |
ALREADY_STARTING = false; | |
reject(`Omnitool server did not start within the timeout period.`); | |
} | |
}); | |
}); | |
} | |
async function startRequestForwardingServer(proxy_port) | |
{ | |
const server = http.createServer((req, res) => handleRoutes(req, res, proxy_port)); | |
server.listen(proxy_port, '0.0.0.0'); | |
console.log(`Request forwarding server listening on port ${proxy_port}`); | |
} | |
async function handleRoutes(req, res, proxy_port) | |
{ | |
const localUrl = req.headers['host']; | |
let htmlContent = ''; | |
const hostname = localUrl.split(':')[0]; | |
const hostport = localUrl.split(':')[1] || PROXY_PORT_HUGGINGFACE; | |
const newUrl = `${PROTOCOL}://${hostname}:${PROXY_PORT_OMNITOOL}`; | |
//console.log(`hostname = ${hostname}, hostport = ${hostport}, newUrl = ${newUrl}`); | |
if (!OMNITOOL_READY) | |
{ | |
if (req.method === 'GET') | |
{ | |
switch (req.url) | |
{ | |
case '/start-omnitool-server': | |
{ | |
console.log(`Omnitool Server:ALREADY_STARTING = ${ALREADY_STARTING}`); | |
if (ALREADY_STARTING) | |
{ | |
res.writeHead(200, { 'Content-Type': 'text/html' }); | |
res.end("Omnitool server already starting"); | |
return; | |
} | |
try | |
{ | |
await startOmnitoolServer(); | |
res.writeHead(200, { 'Content-Type': 'text/html' }); | |
res.end("Omnitool server started successfully"); | |
} | |
catch (error) | |
{ | |
console.error(error); | |
ALREADY_STARTING = false; | |
res.writeHead(500, { 'Content-Type': 'text/html' }); | |
res.end(`Error starting Omnitool server: ${error}`); | |
} | |
return; | |
} | |
case '/omnitool-logs': | |
{ | |
res.writeHead(200, { 'Content-Type': 'application/json' }); | |
const reply = { logs: omnitoolLogs, ready: OMNITOOL_PRE_READY }; | |
res.end(JSON.stringify(reply)); | |
return; | |
} | |
case '/': | |
{ | |
if (hostport === PROXY_PORT_OMNITOOL.toString()) | |
{ | |
console.log(`Serving the page with START OMNITOOL SERVER button`); | |
htmlContent = ` | |
<html> | |
<head> | |
<title>Proxy Server</title> | |
<style> | |
#logContainer { | |
height: 400px; /* Fixed height */ | |
overflow-y: scroll; /* Enable vertical scrolling */ | |
background-color: black; | |
color: lime; | |
font-family: 'Courier New', Courier, monospace; | |
padding: 10px; | |
white-space: pre-wrap; /* Keep whitespaces */ | |
border: 1px solid #ddd; | |
} | |
</style> | |
</head> | |
<body> | |
<button id="startServerButton" onclick="startServer()">Start Omnitool Server</button> | |
<div id="logContainer"></div> | |
<script> | |
function startServer() { | |
document.getElementById('startServerButton').disabled = true; | |
fetch('/start-omnitool-server') | |
.then(response => response.json()) | |
.then(data => { | |
startLogPolling(); | |
}); | |
} | |
function startLogPolling() { | |
const interval = setInterval(() => { | |
fetch('/omnitool-logs') | |
.then(response => response.json()) | |
.then(data => { | |
const logContainer = document.getElementById('logContainer'); | |
logContainer.innerText = data.logs.join(""); | |
if (data.ready) { | |
data.logs.push("Omnitool is ready! REFRESHING PAGE..."); | |
logContainer.innerText = data.logs.join(""); | |
clearInterval(interval); | |
setTimeout(function() { | |
window.location.reload(1); | |
}, 1500); // Refreshes after 1.5 seconds | |
} | |
scrollToBottom(logContainer); | |
}); | |
}, 500); // Adjust to 500 for efficiency | |
} | |
function scrollToBottom(element) { | |
element.scrollTop = element.scrollHeight; | |
} | |
startLogPolling(); | |
</script> | |
</body> | |
</html>`; | |
} | |
else | |
{ | |
console.log(`Serving the page with START OMNITOOL SERVER button and GOTO ${newUrl} button`); | |
htmlContent = ` | |
<html> | |
<head> | |
<title>Proxy Server</title> | |
<style> | |
#logContainer { | |
height: 400px; /* Fixed height */ | |
overflow-y: scroll; /* Enable vertical scrolling */ | |
background-color: black; | |
color: lime; | |
font-family: 'Courier New', Courier, monospace; | |
padding: 10px; | |
white-space: pre-wrap; /* Keep whitespaces */ | |
border: 1px solid #ddd; | |
} | |
.highlight-button { | |
animation: pulseAnimation 1s infinite; | |
background-color: yellow; | |
color: black; | |
font-weight: bold; | |
} | |
@keyframes pulseAnimation { | |
0% { transform: scale(1); } | |
50% { transform: scale(1.1); } | |
100% { transform: scale(1); } | |
} | |
</style> | |
</head> | |
<body> | |
<button id="startServerButton" onclick="startServer()">Start Omnitool Server</button> | |
<button id="exitIframeButton" onclick="exitIframe()">GOTO ${newUrl}</button> | |
<div id="logContainer"></div> | |
<script> | |
function exitIframe() { | |
window.open('${newUrl}', '_blank'); | |
} | |
function startServer() { | |
document.getElementById('startServerButton').disabled = true; | |
fetch('/start-omnitool-server') | |
.then(response => response.json()) | |
.then(data => { | |
startLogPolling(); | |
}); | |
} | |
function highlightExitButton() { | |
const exitButton = document.getElementById('exitIframeButton'); | |
exitButton.classList.add('highlight-button'); | |
} | |
function startLogPolling() { | |
const interval = setInterval(() => { | |
fetch('/omnitool-logs') | |
.then(response => response.json()) | |
.then(data => { | |
const logContainer = document.getElementById('logContainer'); | |
logContainer.innerText = data.logs.join(""); | |
if (data.ready) { | |
data.logs.push("Omnitool is ready! REFRESHING PAGE..."); | |
logContainer.innerText = data.logs.join(""); | |
clearInterval(interval); | |
highlightExitButton(); | |
} | |
scrollToBottom(logContainer); | |
}); | |
}, 250); // Adjust to 500 for efficiency | |
} | |
function scrollToBottom(element) { | |
element.scrollTop = element.scrollHeight; | |
} | |
startLogPolling(); | |
</script> | |
</body> | |
</html>`; | |
} | |
res.writeHead(200, { 'Content-Type': 'text/html' }); | |
res.end(htmlContent); | |
return; | |
} | |
default: | |
console.log(`Doing nothing with this request: ${req.url}`); | |
res.writeHead(200, { 'Content-Type': 'text/html' }); | |
res.end(` | |
<html> | |
<head> | |
<title>Page Refresh</title> | |
<script> | |
setTimeout(function() { | |
window.location.reload(1); | |
}, 5000); // Refreshes after 5 seconds | |
</script> | |
</head> | |
<body> | |
<p>Doing nothing with this request: ${req.url}</p> | |
<p>The page will refresh automatically in 5 seconds.</p> | |
</body> | |
</html>`); | |
return; | |
} | |
} | |
// we are dropping anything that isn't a GET request | |
res.writeHead(200, { 'Content-Type': 'text/html' }); | |
res.end(` | |
<html> | |
<head> | |
<title>Page Refresh</title> | |
<script> | |
setTimeout(function() { | |
window.location.reload(1); | |
}, 1000); // Refreshes after 1 seconds | |
</script> | |
</head> | |
<body> | |
<p>Doing nothing with this request: ${req.url}</p> | |
<p>The page will refresh automatically in 1 seconds.</p> | |
</body> | |
</html>`); | |
return; | |
} | |
if (OMNITOOL_READY) | |
{ | |
if (proxy_port === PROXY_PORT_HUGGINGFACE) | |
{ | |
htmlContent = ` | |
<html> | |
<head> | |
<title>Proxy Server</title> | |
<style> | |
#logContainer { | |
height: 400px; /* Fixed height */ | |
overflow-y: scroll; /* Enable vertical scrolling */ | |
background-color: black; | |
color: lime; | |
font-family: 'Courier New', Courier, monospace; | |
padding: 10px; | |
white-space: pre-wrap; /* Keep whitespaces */ | |
border: 1px solid #ddd; | |
} | |
.highlight-button { | |
animation: pulseAnimation 1s infinite; | |
background-color: yellow; | |
color: black; | |
font-weight: bold; | |
} | |
@keyframes pulseAnimation { | |
0% { transform: scale(1); } | |
50% { transform: scale(1.1); } | |
100% { transform: scale(1); } | |
} | |
</style> | |
</head> | |
<body> | |
<button id="exitIframeButton" onclick="exitIframe()">GOTO ${newUrl}</button> | |
<div id="logContainer"></div> | |
<script> | |
function exitIframe() { | |
window.open('${newUrl}', '_blank'); | |
} | |
function highlightExitButton() { | |
const exitButton = document.getElementById('exitIframeButton'); | |
exitButton.classList.add('highlight-button'); | |
} | |
highlightExitButton(); | |
element.scrollTop = element.scrollHeight; | |
</script> | |
</body> | |
</html>`; | |
res.writeHead(200, { 'Content-Type': 'text/html' }); | |
res.end(htmlContent); | |
return; | |
} | |
if (proxy_port === PROXY_PORT_OMNITOOL) | |
{ | |
// Proxy logic... | |
const options = { hostname: CONTAINER_HOST, port: CONTAINER_PORT_OMNITOOL, path: req.url, method: req.method, headers: req.headers, }; | |
const proxy = http.request(options, (proxyRes) => | |
{ | |
res.writeHead(proxyRes.statusCode, proxyRes.headers); | |
proxyRes.pipe(res, { end: true }); | |
}); | |
req.pipe(proxy, { end: true }); | |
return; | |
} | |
} | |
/* | |
// Proxy logic... | |
const options = { hostname: CONTAINER_HOST, port: CONTAINER_PORT_OMNITOOL, path: req.url, method: req.method, headers: req.headers, }; | |
const proxy = http.request(options, (proxyRes) => | |
{ | |
res.writeHead(proxyRes.statusCode, proxyRes.headers); | |
proxyRes.pipe(res, { end: true }); | |
}); | |
req.pipe(proxy, { end: true }); | |
*/ | |
return; | |
} | |
// Main function to start everything | |
async function startManagementServer() | |
{ | |
try | |
{ | |
await startRequestForwardingServer(PROXY_PORT_HUGGINGFACE); | |
await startRequestForwardingServer(PROXY_PORT_OMNITOOL); | |
} catch (error) | |
{ | |
console.error('Failed to start servers:', error); | |
} | |
} | |
// main | |
// Start the servers | |
startManagementServer(); | |