UNPKG

cassava

Version:
113 lines 4.97 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ProxyRoute = void 0; const http = require("http"); const https = require("https"); const querystring = require("querystring"); const url = require("url"); /** * Proxies requests to another server. */ class ProxyRoute { constructor(config) { this.config = config; if (!config) { throw new Error("config must be set"); } if (typeof config.srcPath !== "string") { throw new Error("config.srcPath must be set"); } if (!config.srcPath.startsWith("/")) { throw new Error("config.srcPath must start with `/`"); } if (config.srcPath.includes("?") || config.srcPath.includes("#")) { throw new Error("config.srcPath cannot define a query or hash"); } if (typeof config.destPath !== "string") { throw new Error("config.destPath must be set"); } if (!config.destPath.match(/^https?:\/\//)) { throw new Error("config.destPath must start with http:// or https://"); } if (config.destPath.includes("?") || config.destPath.includes("#")) { throw new Error("config.destPath cannot define a query or hash"); } this.parsedDest = url.parse ? url.parse(config.destPath) : new url.URL(config.destPath); } matches(evt) { return evt.path.startsWith(this.config.srcPath) && (evt.path.length === this.config.srcPath.length || this.config.srcPath.endsWith("/") || evt.path[this.config.srcPath.length] === "/"); } handle(evt) { return __awaiter(this, void 0, void 0, function* () { let reqArgs = { protocol: this.parsedDest.protocol, hostname: this.parsedDest.hostname, method: evt.httpMethod, headers: Object.assign(Object.assign({}, evt.headers), this.config.additionalHeaders), path: this.parsedDest.path + evt.path.substr(this.config.srcPath.length) }; if (evt.multiValueQueryStringParameters) { const q = querystring.stringify(evt.multiValueQueryStringParameters); if (q.length) { reqArgs.path += "?" + q; } } if (this.config.requestMapper) { reqArgs = yield this.config.requestMapper(reqArgs); if (!reqArgs) { return null; } } let body = evt.body; if (body && this.config.bodyMapper) { body = yield this.config.bodyMapper(body); } let bodyContentType = body && this.getRequestBodyContentType(reqArgs); if (body && !bodyContentType) { bodyContentType = reqArgs.headers["Content-Type"] = "application/json"; } // Do this manually so as to not create another dependency. return new Promise((resolve, reject) => { const reqFunction = reqArgs.protocol === "http:" ? http.request : https.request; const req = reqFunction(reqArgs, res => { const response = { statusCode: res.statusCode, headers: res.headers, body: "" }; res.on("data", d => response.body += d); res.on("end", () => resolve(response)); }); req.on("error", e => reject(e)); if (body !== undefined) { if (typeof body === "string" && !bodyContentType.match(/json$/)) { req.write(body); } else { req.write(JSON.stringify(body)); } } req.end(); }); }); } getRequestBodyContentType(reqArgs) { for (const header of Object.keys(reqArgs.headers)) { if (header.toLowerCase() === "content-type") { return reqArgs.headers[header]; } } return null; } } exports.ProxyRoute = ProxyRoute; //# sourceMappingURL=ProxyRoute.js.map