Bones/node_modules/browser-sync/lib/server/proxy-server.js
SOUTHERNCO\x2mjbyrn 7efe7605b8 Template Upload
2017-05-17 13:45:25 -04:00

196 lines
5.1 KiB
JavaScript

"use strict";
var httpProxy = require("http-proxy");
var utils = require("./utils");
var proxyUtils = require("./proxy-utils");
var Immutable = require("immutable");
var Map = require("immutable").Map;
var List = require("immutable").List;
/**
* Default options that are passed along to http-proxy
*/
var defaultHttpProxyOptions = Map({
/**
* This ensures targets are more likely to
* accept each request
*/
changeOrigin: true,
/**
* This handles redirects
*/
autoRewrite: true,
/**
* This allows our self-signed certs to be used for development
*/
secure: false,
ws: true
});
var defaultCookieOptions = Map({
stripDomain: true
});
var ProxyOption = Immutable.Record({
route: "",
target: "",
rewriteRules: true,
/**
* Functions to be called on proxy request
* with args [proxyReq, req, res, options]
*/
proxyReq: List([]),
/**
* Functions to be called on proxy response
* with args [proxyRes, req, res]
*/
proxyRes: List([]),
/**
* Functions to be called on proxy response
* with args [proxyReq, req, socket, options, head]
*/
proxyReqWs: List([]),
errHandler: undefined,
url: Map({}),
proxyOptions: Map(defaultHttpProxyOptions),
cookies: Map(defaultCookieOptions),
ws: false,
middleware: List([]),
reqHeaders: undefined
});
/**
* @param {BrowserSync} bs
* @param {String} scripts
* @returns {*}
*/
module.exports = function createProxyServer (bs) {
var opt = new ProxyOption().mergeDeep(bs.options.get("proxy"));
var proxy = httpProxy.createProxyServer(opt.get("proxyOptions").set("target", opt.get("target")).toJS());
var target = opt.get("target");
var proxyReq = getProxyReqFunctions(opt.get("proxyReq"), opt, bs);
var proxyRes = getProxyResFunctions(opt.get("proxyRes"), opt);
var proxyResWs = opt.get("proxyReqWs");
bs.options = bs.options.update("middleware", function (mw) {
return mw.concat({
id: "Browsersync Proxy",
route: opt.get("route"),
handle: function (req, res) {
proxy.web(req, res, {
target: target
});
}
});
});
var app = utils.getBaseApp(bs);
/**
* @type {*|{server, app}}
*/
var browserSyncServer = utils.getServer(app, bs.options);
browserSyncServer.proxy = proxy;
if (opt.get("ws")) {
// debug(`+ ws upgrade for: ${x.get("target")}`);
browserSyncServer.server.on("upgrade", function (req, socket, head) {
proxy.ws(req, socket, head);
});
}
/**
* Add any user provided functions for proxyReq, proxyReqWs and proxyRes
*/
applyFns("proxyReq", proxyReq);
applyFns("proxyRes", proxyRes);
applyFns("proxyReqWs", proxyResWs);
/**
* Handle Proxy errors
*/
proxy.on("error", function (err) {
if (typeof opt.get("errHandler") === "function") {
opt.get("errHandler").call(null, err);
}
});
/**
* Apply functions to proxy events
* @param {string} name - the name of the http-proxy event
* @param {Array} fns - functions to call on each event
*/
function applyFns (name, fns) {
if (!List.isList(fns)) fns = [fns];
proxy.on(name, function () {
var args = arguments;
fns.forEach(function(fn) {
if (typeof fn === "function") {
fn.apply(null, args);
}
});
});
}
return browserSyncServer;
};
/**
* @param resFns
* @returns {*}
*/
function getProxyResFunctions (resFns, opt) {
if (opt.getIn(["cookies", "stripDomain"])) {
return resFns.push(proxyUtils.checkCookies);
}
return resFns;
}
/**
* @param reqFns
* @returns {*}
*/
function getProxyReqFunctions (reqFns, opt, bs) {
var reqHeaders = opt.getIn(["reqHeaders"]);
if (!reqHeaders) {
return reqFns;
}
/**
* Back-compat for old `reqHeaders` option here a
* function was given that returned an object
* where key:value was header-name:header-value
* This didn't really work as it clobbered all other headers,
* but it remains for the unlucky few who used it.
*/
if (typeof reqHeaders === "function") {
var output = reqHeaders.call(bs, opt.toJS());
if (Object.keys(output).length) {
return reqFns.concat(function (proxyReq) {
Object.keys(output).forEach(function (key) {
proxyReq.setHeader(key, output[key]);
});
});
}
}
/**
* Now, if {key:value} given, set the each header
*
* eg: reqHeaders: {
* 'is-dev': 'true'
* }
*/
if (Map.isMap(reqHeaders)) {
return reqFns.concat(function (proxyReq) {
reqHeaders.forEach(function (value, key) {
proxyReq.setHeader(key, value);
});
});
}
return reqFns;
}