@reedchan/koa-http-proxy
Version:
http proxy middleware for koa
119 lines (96 loc) • 2.7 kB
JavaScript
;
var http = require("http");
var https = require("https");
var url = require("url");
var getRawBody = require("raw-body");
var isUnset = require("./isUnset");
function extend(obj, source, skips) {
if (!source) {
return obj;
}
for (var prop in source) {
if (!skips || skips.indexOf(prop) === -1) {
obj[prop] = source[prop];
}
}
return obj;
}
function parseHost(Container) {
var host = Container.params.host;
var ctx = Container.user.ctx;
var options = Container.options;
host = typeof host === "function" ? host(ctx) : host.toString();
if (!host) {
return new Error("Empty host parameter");
}
if (!/http(s)?:\/\//.test(host)) {
host = "http://" + host;
}
var parsed = url.parse(host);
if (!parsed.hostname) {
return new Error("Unable to parse hostname, possibly missing protocol://?");
}
var ishttps = options.https || parsed.protocol === "https:";
return {
host: parsed.hostname,
port: parsed.port || (ishttps ? 443 : 80),
isSecure: ishttps,
module: ishttps ? https : http,
};
}
function reqHeaders(ctx, options) {
var headers = options.headers || {};
var skipHdrs = ["connection", "content-length"];
if (!options.preserveHostHdr) {
skipHdrs.push("host");
}
return extend(headers, ctx.headers, skipHdrs);
}
function createRequestOptions(ctx, options) {
// prepare proxyRequest
var reqOpt = {
headers: reqHeaders(ctx, options),
method: ctx.method,
path: ctx.path,
// params: req.params,
};
if (options.preserveReqSession) {
reqOpt.session = ctx.session;
}
if (options.agent) {
reqOpt.agent = options.agent;
}
return Promise.resolve(reqOpt);
}
// extract to bodyContent object
function bodyContent(ctx, options) {
var parseReqBody = isUnset(options.parseReqBody)
? true
: options.parseReqBody;
// HTTP methods that should not have a request body
var methodsWithoutBody = ["GET", "HEAD", "DELETE", "OPTIONS"];
var method = ctx.method.toUpperCase();
// Don't parse body for methods that shouldn't have one
if (methodsWithoutBody.indexOf(method) !== -1) {
return Promise.resolve(null);
}
function maybeParseBody(ctx, limit) {
if (ctx.request.body) {
return Promise.resolve(ctx.request.body);
} else {
// Returns a promise if no callback specified and global Promise exists.
return getRawBody(ctx.req, {
length: ctx.headers["content-length"],
limit: limit,
});
}
}
if (parseReqBody) {
return maybeParseBody(ctx, options.limit || "1mb");
}
}
module.exports = {
create: createRequestOptions,
bodyContent: bodyContent,
parseHost: parseHost,
};