W72crm_web-master/node_modules/http-proxy-middleware/lib/index.js

153 lines
4.8 KiB
JavaScript

var _ = require('lodash')
var httpProxy = require('http-proxy')
var configFactory = require('./config-factory')
var handlers = require('./handlers')
var contextMatcher = require('./context-matcher')
var PathRewriter = require('./path-rewriter')
var Router = require('./router')
var logger = require('./logger').getInstance()
var getArrow = require('./logger').getArrow
module.exports = HttpProxyMiddleware
function HttpProxyMiddleware (context, opts) {
// https://github.com/chimurai/http-proxy-middleware/issues/57
var wsUpgradeDebounced = _.debounce(handleUpgrade)
var wsInitialized = false
var config = configFactory.createConfig(context, opts)
var proxyOptions = config.options
// create proxy
var proxy = httpProxy.createProxyServer({})
logger.info('[HPM] Proxy created:', config.context, ' -> ', proxyOptions.target)
var pathRewriter = PathRewriter.create(proxyOptions.pathRewrite) // returns undefined when "pathRewrite" is not provided
// attach handler to http-proxy events
handlers.init(proxy, proxyOptions)
// log errors for debug purpose
proxy.on('error', logError)
// https://github.com/chimurai/http-proxy-middleware/issues/19
// expose function to upgrade externally
middleware.upgrade = wsUpgradeDebounced
return middleware
function middleware (req, res, next) {
if (shouldProxy(config.context, req)) {
var activeProxyOptions = prepareProxyRequest(req)
proxy.web(req, res, activeProxyOptions)
} else {
next()
}
if (proxyOptions.ws === true) {
// use initial request to access the server object to subscribe to http upgrade event
catchUpgradeRequest(req.connection.server)
}
}
function catchUpgradeRequest (server) {
// subscribe once; don't subscribe on every request...
// https://github.com/chimurai/http-proxy-middleware/issues/113
if (!wsInitialized) {
server.on('upgrade', wsUpgradeDebounced)
wsInitialized = true
}
}
function handleUpgrade (req, socket, head) {
// set to initialized when used externally
wsInitialized = true
if (shouldProxy(config.context, req)) {
var activeProxyOptions = prepareProxyRequest(req)
proxy.ws(req, socket, head, activeProxyOptions)
logger.info('[HPM] Upgrading to WebSocket')
}
}
/**
* Determine whether request should be proxied.
*
* @private
* @param {String} context [description]
* @param {Object} req [description]
* @return {Boolean}
*/
function shouldProxy (context, req) {
var path = (req.originalUrl || req.url)
return contextMatcher.match(context, path, req)
}
/**
* Apply option.router and option.pathRewrite
* Order matters:
* Router uses original path for routing;
* NOT the modified path, after it has been rewritten by pathRewrite
* @param {Object} req
* @return {Object} proxy options
*/
function prepareProxyRequest (req) {
// https://github.com/chimurai/http-proxy-middleware/issues/17
// https://github.com/chimurai/http-proxy-middleware/issues/94
req.url = (req.originalUrl || req.url)
// store uri before it gets rewritten for logging
var originalPath = req.url
var newProxyOptions = _.assign({}, proxyOptions)
// Apply in order:
// 1. option.router
// 2. option.pathRewrite
__applyRouter(req, newProxyOptions)
__applyPathRewrite(req, pathRewriter)
// debug logging for both http(s) and websockets
if (proxyOptions.logLevel === 'debug') {
var arrow = getArrow(originalPath, req.url, proxyOptions.target, newProxyOptions.target)
logger.debug('[HPM] %s %s %s %s', req.method, originalPath, arrow, newProxyOptions.target)
}
return newProxyOptions
}
// Modify option.target when router present.
function __applyRouter (req, options) {
var newTarget
if (options.router) {
newTarget = Router.getTarget(req, options)
if (newTarget) {
logger.debug('[HPM] Router new target: %s -> "%s"', options.target, newTarget)
options.target = newTarget
}
}
}
// rewrite path
function __applyPathRewrite (req, pathRewriter) {
if (pathRewriter) {
var path = pathRewriter(req.url, req)
if (typeof path === 'string') {
req.url = path
} else {
logger.info('[HPM] pathRewrite: No rewritten path found. (%s)', req.url)
}
}
}
function logError (err, req, res) {
var hostname = (req.headers && req.headers.host) || (req.hostname || req.host) // (websocket) || (node0.10 || node 4/5)
var target = proxyOptions.target.host || proxyOptions.target
var errorMessage = '[HPM] Error occurred while trying to proxy request %s from %s to %s (%s) (%s)'
var errReference = 'https://nodejs.org/api/errors.html#errors_common_system_errors' // link to Node Common Systems Errors page
logger.error(errorMessage, req.url, hostname, target, err.code, errReference)
}
}