ProxyManager.coffee 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. settings = require 'settings-sharelatex'
  2. logger = require 'logger-sharelatex'
  3. request = require 'request'
  4. URL = require 'url'
  5. module.exports = ProxyManager =
  6. apply: (publicApiRouter) ->
  7. for proxyUrl, target of settings.proxyUrls
  8. do (target) ->
  9. method = target.options?.method || 'get'
  10. publicApiRouter[method] proxyUrl, ProxyManager.createProxy(target)
  11. createProxy: (target) ->
  12. (req, res, next) ->
  13. targetUrl = makeTargetUrl(target, req)
  14. logger.log targetUrl: targetUrl, reqUrl: req.url, "proxying url"
  15. options =
  16. url: targetUrl
  17. options.headers = { Cookie: req.headers.cookie } if req.headers?.cookie
  18. Object.assign(options, target.options) if target?.options?
  19. options.form = req.body if options.method in ['post', 'put']
  20. upstream = request(options)
  21. upstream.on "error", (error) ->
  22. logger.error err: error, "error in ProxyManager"
  23. # TODO: better handling of status code
  24. # see https://github.com/overleaf/write_latex/wiki/Streams-and-pipes-in-Node.js
  25. upstream.pipe(res)
  26. # make a URL from a proxy target.
  27. # if the query is specified, set/replace the target's query with the given query
  28. makeTargetUrl = (target, req) ->
  29. targetUrl = URL.parse(parseSettingUrl(target, req))
  30. if req.query? and Object.keys(req.query).length > 0
  31. targetUrl.query = req.query
  32. targetUrl.search = null # clear `search` as it takes precedence over `query`
  33. targetUrl.format()
  34. parseSettingUrl = (target, { params }) ->
  35. return target if typeof target is 'string'
  36. if typeof target.path is 'function'
  37. path = target.path(params)
  38. else
  39. path = target.path
  40. "#{target.baseUrl}#{path or ''}"