| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 | 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').getArrowmodule.exports = HttpProxyMiddlewarefunction 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 || err,      errReference    )  }}
 |