diff --git a/package.json b/package.json index 32109138..99f759a0 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,6 @@ "mnemonist": "^0.40.3", "mobile-drag-drop": "3.0.0-rc.0", "msgpackr": "1.10.1", - "node-fetch": "2", "node-html-parser": "^6.1.12", "ollama": "^0.5.0", "pdfjs-dist": "^4.0.379", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c460c2c9..f247c718 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -158,15 +158,15 @@ importers: ml-distance: specifier: ^4.0.1 version: 4.0.1 + mnemonist: + specifier: ^0.40.3 + version: 0.40.3 mobile-drag-drop: specifier: 3.0.0-rc.0 version: 3.0.0-rc.0 msgpackr: specifier: 1.10.1 version: 1.10.1 - node-fetch: - specifier: '2' - version: 2.7.0 node-html-parser: specifier: ^6.1.12 version: 6.1.12 @@ -2756,6 +2756,9 @@ packages: ml-tree-similarity@1.0.0: resolution: {integrity: sha512-XJUyYqjSuUQkNQHMscr6tcjldsOoAekxADTplt40QKfwW6nd++1wHWV9AArl0Zvw/TIHgNaZZNvr8QGvE8wLRg==} + mnemonist@0.40.3: + resolution: {integrity: sha512-Vjyr90sJ23CKKH/qPAgUKicw/v6pRoamxIEDFOF8uSgFME7DqPRpHgRTejWVjkdGg5dXj0/NyxZHZ9bcjH+2uQ==} + mobile-drag-drop@3.0.0-rc.0: resolution: {integrity: sha512-f8wIDTbBYLBW/+5sei1cqUE+StyDpf/LP+FRZELlVX6tmOOmELk84r3wh1z3woxCB9G5octhF06K5COvFjGgqg==} @@ -2900,6 +2903,9 @@ packages: object-inspect@1.13.1: resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + obliterator@2.0.5: + resolution: {integrity: sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==} + ollama@0.5.0: resolution: {integrity: sha512-CRtRzsho210EGdK52GrUMohA2pU+7NbgEaBG3DcYeRmvQthDO7E2LHOkLlUUeaYUlNmEd8icbjC02ug9meSYnw==} @@ -6505,6 +6511,10 @@ snapshots: binary-search: 1.3.6 num-sort: 2.1.0 + mnemonist@0.40.3: + dependencies: + obliterator: 2.0.5 + mobile-drag-drop@3.0.0-rc.0: {} modify-values@1.0.1: {} @@ -6665,6 +6675,8 @@ snapshots: object-inspect@1.13.1: {} + obliterator@2.0.5: {} + ollama@0.5.0: dependencies: whatwg-fetch: 3.6.20 diff --git a/server/node/server.cjs b/server/node/server.cjs index b2871d9d..6e16bcce 100644 --- a/server/node/server.cjs +++ b/server/node/server.cjs @@ -11,8 +11,7 @@ app.use(express.raw({ type: 'application/octet-stream', limit: '50mb' })); const {pipeline} = require('stream/promises') const https = require('https'); const sslPath = path.join(process.cwd(), 'server/node/ssl/certificate'); -const EXTERNAL_HUB_URL = 'https://sv.risuai.xyz'; -const fetch = require('node-fetch'); +const hubURL = 'https://sv.risuai.xyz'; let password = '' @@ -31,12 +30,17 @@ function isHex(str) { } app.get('/', async (req, res, next) => { - console.log("[Server] Connected") + + const clientIP = req.headers['x-forwarded-for'] || req.ip || req.socket.remoteAddress || 'Unknown IP'; + const timestamp = new Date().toISOString(); + console.log(`[Server] ${timestamp} | Connection from: ${clientIP}`); + try { const mainIndex = await fs.readFile(path.join(process.cwd(), 'dist', 'index.html')) const root = htmlparser.parse(mainIndex) const head = root.querySelector('head') head.innerHTML = `` + head.innerHTML + res.send(root.toString()) } catch (error) { console.log(error) @@ -139,116 +143,49 @@ const reverseProxyFunc_get = async (req, res, next) => { } } -// Risu Realm Proxy -async function hubProxyHandler(req, res, next) { +async function hubProxyFunc(req, res) { + try { - // Extract request path and query parameters const pathAndQuery = req.originalUrl.replace(/^\/hub-proxy/, ''); - const externalURL = EXTERNAL_HUB_URL + pathAndQuery; - - console.log(`[Hub Proxy] Forwarding ${req.method} request to: ${externalURL}`); - - // Prepare headers to send to the realm server (including Accept-Encoding modification) + const externalURL = hubURL + pathAndQuery; + const headersToSend = { ...req.headers }; - delete headersToSend['host']; - delete headersToSend['connection']; - headersToSend['accept-encoding'] = 'gzip, deflate'; // Exclude zstd, etc. - if (!headersToSend['x-forwarded-for']) { - headersToSend['x-forwarded-for'] = req.ip; - } - - // Execute the fetch request to the realm server - const response = await fetch(externalURL, { + delete headersToSend.host; + delete headersToSend.connection; + + const proxyReq = new Request(externalURL, { method: req.method, headers: headersToSend, - body: (req.method !== 'GET' && req.method !== 'HEAD') ? req.body : undefined, + body: req.method !== 'GET' && req.method !== 'HEAD' ? req : undefined, + duplex: 'half' }); - - console.log(`[Hub Proxy] Received status ${response.status} from external server`); - - // Handle the realm server response - // Clean up response headers and extract Content-Type - const responseHeaders = {}; - // Check the Content-Type of the realm server response (use default if missing) - let contentType = response.headers.get('content-type') || 'application/octet-stream'; - - response.headers.forEach((value, key) => { - const lowerKey = key.toLowerCase(); - // List of headers not to be forwarded to the client - const excludedHeaders = [ - 'transfer-encoding', 'connection', 'content-encoding', - 'access-control-allow-origin', 'access-control-allow-methods', - 'access-control-allow-headers', 'content-security-policy', - 'content-security-policy-report-only', 'clear-site-data', - 'strict-transport-security', 'expect-ct', - 'cf-ray', 'cf-cache-status', 'report-to', 'nel', 'server', 'server-timing', 'alt-svc' - ]; - if (!excludedHeaders.includes(lowerKey)) { - responseHeaders[key] = value; - } - }); - - // Set the status code and cleaned headers for the client - res.status(response.status).set(responseHeaders); - - // Determine body processing method based on Content-Type - try { - if (contentType.startsWith('application/json')) { - // JSON response: read as text and send - const bodyText = await response.text(); - console.log(`[Hub Proxy] Processing JSON response (size: ${bodyText.length})`); - res.setHeader('Content-Type', contentType); // Set the final Content-Type - res.send(bodyText); - - } else if (contentType.startsWith('image/')) { - // Image response: read as buffer and send - const bodyBuffer = await response.buffer(); // Assuming 'fetch' response object has a .buffer() method or similar - console.log(`[Hub Proxy] Processing Image response (type: ${contentType}, size: ${bodyBuffer.length} bytes)`); - res.setHeader('Content-Type', contentType); // Set the final Content-Type - res.send(bodyBuffer); - - } else { - // Other responses (HTML, other text, unknown binary, etc.): read as buffer and send safely - const bodyBuffer = await response.buffer(); // Assuming 'fetch' response object has a .buffer() method or similar - console.log(`[Hub Proxy] Processing Other response as buffer (type: ${contentType}, size: ${bodyBuffer.length} bytes)`); - // Use original Content-Type if available, otherwise use octet-stream (already handled by default assignment) - res.setHeader('Content-Type', contentType); - res.send(bodyBuffer); - } - } catch (bodyError) { - // If an error occurs while reading/processing the response body - console.error("[Hub Proxy] Error reading/processing response body:", bodyError); - if (!res.headersSent) { - res.status(500).send({ error: 'Failed to process response body from hub server.' }); - } else { - console.error("[Hub Proxy] Headers already sent, cannot send body error to client."); - res.end(); - } - return; // End the handler + + const response = await fetch(proxyReq); + + for (const [key, value] of response.headers.entries()) { + res.setHeader(key, value); } - + res.status(response.status); + + await pipeline(response.body, res); + } catch (error) { - // Fetch request itself failed or other exceptions - console.error("[Hub Proxy] Request failed:", error); + console.error("[Hub Proxy] Error:", error); if (!res.headersSent) { - res.status(502).send({ error: 'Proxy failed to connect to or get response from the hub server.' }); + res.status(502).send({ error: 'Proxy request failed' }); } else { - console.error("[Hub Proxy] Headers already sent, cannot send connection error to client."); res.end(); } } } -app.get('/hub-proxy/*', hubProxyHandler); -app.post('/hub-proxy/*', hubProxyHandler); -app.put('/hub-proxy/*', hubProxyHandler); - app.get('/proxy', reverseProxyFunc_get); app.get('/proxy2', reverseProxyFunc_get); +app.get('/hub-proxy/*', hubProxyFunc); app.post('/proxy', reverseProxyFunc); app.post('/proxy2', reverseProxyFunc); - +app.post('/hub-proxy/*', hubProxyFunc); app.get('/api/password', async(req, res)=> { if(password === ''){ @@ -408,9 +345,6 @@ async function getHttpsOptions() { const keyPath = path.join(sslPath, 'server.key'); const certPath = path.join(sslPath, 'server.crt'); - console.log(keyPath) - console.log(certPath) - try { await fs.access(keyPath);