UNPKG

f2e-server3

Version:

f2e-server 3.0

177 lines (176 loc) 8.51 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const engine_1 = require("../../utils/engine"); const http = __importStar(require("node:http")); const https = __importStar(require("node:https")); const renderItem_1 = require("./renderItem"); const resp_1 = require("../../utils/resp"); const utils_1 = require("../../utils"); const fs = __importStar(require("node:fs")); const path = __importStar(require("node:path")); const middleware_proxy = { name: 'proxy', mode: ['dev', 'prod'], execute: (conf) => { const { proxies = [] } = conf; if (proxies.length === 0) { return; } const items = proxies.map(renderItem_1.renderItem); return { beforeRoute(pathname, ctx) { const { req, resp } = ctx; const url = req.getUrl(); const search = req.getQuery(); const item = items.find(item => { return item.match(url, ctx); }); if (!item) { return; } const origin = item.getOrigin(url, ctx); const { timeout = 5000, requestOptions = {}, requestHeaders = h => h, responseHeaders = h => h, responseRender = h => h, } = item; const newPath = new URL(typeof item.pathname === 'function' ? url.replace(item.location, item.pathname) : url.replace(item.location, item.pathname || (typeof item.location === 'string' ? item.location : '')), origin); if (search) { newPath.search = search; } const isStream = item.stream || false; const saver = item.saver; const _pathname = saver?.pathFixer ? saver.pathFixer(pathname, ctx) : pathname; const dataPath = saver?.pathBodyDir ? path.join(saver.pathBodyDir, _pathname) : null; if (saver && dataPath) { if (!fs.existsSync(saver.pathBodyDir)) { fs.mkdirSync(saver.pathBodyDir, { recursive: true }); } if (!fs.existsSync(saver.pathHeaders)) { fs.mkdirSync(path.dirname(saver.pathHeaders), { recursive: true }); fs.writeFileSync(saver.pathHeaders, JSON.stringify({})); } const proxyHeadersMap = JSON.parse(fs.readFileSync(saver.pathHeaders, 'utf-8')); if (fs.existsSync(dataPath)) { const stats = fs.statSync(dataPath); if (stats.isFile()) { resp.cork(() => { resp.writeStatus('200 OK'); (0, resp_1.commonWriteHeaders)(resp, proxyHeadersMap[_pathname] || {}); resp.write(fs.readFileSync(dataPath)); resp.end(); }); return false; } } } try { const creq = (/^https/i.test(newPath.protocol) ? https : http).request(newPath, { method: req.getMethod(), headers: { ...requestHeaders((0, resp_1.getHttpHeaders)(req), ctx), host: newPath.host, }, timeout: isStream ? 86400000 : timeout, ...requestOptions, }, function (res) { resp.cork(() => { resp.writeStatus(res.statusCode + ' ' + res.statusMessage); (0, resp_1.commonWriteHeaders)(resp, responseHeaders((0, resp_1.getHttpHeaders)(res), res, ctx)); }); const chunks = []; res .on('data', function (data) { if (isStream) { resp.cork(() => { resp.write(data); }); } else { chunks.push(data); } }).on('end', function () { if (isStream) { resp.end(); return; } const result = responseRender(Buffer.concat(chunks), res, ctx); const headers = responseHeaders((0, resp_1.getHttpHeaders)(res), res, ctx); if (saver && dataPath) { const proxyHeadersMap = JSON.parse(fs.readFileSync(saver.pathHeaders, 'utf-8')); proxyHeadersMap[_pathname] = headers; fs.writeFileSync(saver.pathHeaders, JSON.stringify(proxyHeadersMap, null, 2)); if (!fs.existsSync(dataPath)) { fs.mkdirSync(path.dirname(dataPath), { recursive: true }); fs.writeFileSync(dataPath, result); } else if (!fs.statSync(dataPath).isDirectory()) { fs.writeFileSync(dataPath, result); } } resp.cork(() => { resp.write(result); resp.end(); }); }); }).on('timeout', function () { resp.cork(() => { resp.writeStatus('504 Gateway Timeout'); (0, resp_1.commonWriteHeaders)(resp, {}); resp.end('504 Gateway Timeout'); }); }).on('error', function (err) { utils_1.logger.error(`[proxy error]`, newPath, err); }); switch (engine_1.ENGINE_TYPE) { case "node": case "bun": case "deno": req.request.pipe(creq); break; case "uws": resp.onData(function (data, finished) { data && data.byteLength > 0 && creq.write((0, utils_1.toBuffer)(data)); if (finished) { creq.end(); } }); resp.onAborted(() => { creq.destroy(); }); } } catch (e) { resp.cork(() => { resp.writeStatus('502 Bad Gateway'); (0, resp_1.commonWriteHeaders)(resp, {}); resp.end(e + ''); }); } return false; }, }; } }; exports.default = middleware_proxy;