2018-06-18 12:37:58 -04:00
|
|
|
settings = require 'settings-sharelatex'
|
|
|
|
logger = require 'logger-sharelatex'
|
|
|
|
request = require 'request'
|
|
|
|
URL = require 'url'
|
|
|
|
|
|
|
|
module.exports = ProxyManager =
|
2018-07-04 12:59:19 -04:00
|
|
|
apply: (publicApiRouter) ->
|
|
|
|
for proxyUrl, target of settings.proxyUrls
|
|
|
|
do (target) ->
|
2018-07-27 10:43:03 -04:00
|
|
|
method = target.options?.method || 'get'
|
|
|
|
publicApiRouter[method] proxyUrl, ProxyManager.createProxy(target)
|
2018-06-18 12:37:58 -04:00
|
|
|
|
2018-07-04 12:59:19 -04:00
|
|
|
createProxy: (target) ->
|
|
|
|
(req, res, next) ->
|
|
|
|
targetUrl = makeTargetUrl(target, req)
|
|
|
|
logger.log targetUrl: targetUrl, reqUrl: req.url, "proxying url"
|
2018-06-18 12:37:58 -04:00
|
|
|
|
2018-07-27 10:43:03 -04:00
|
|
|
options =
|
|
|
|
url: targetUrl
|
|
|
|
options.headers = { Cookie: req.headers.cookie } if req.headers?.cookie
|
|
|
|
Object.assign(options, target.options) if target?.options?
|
|
|
|
options.form = req.body if options.method in ['post', 'put']
|
|
|
|
upstream = request(options)
|
2018-07-04 12:59:19 -04:00
|
|
|
upstream.on "error", (error) ->
|
|
|
|
logger.error err: error, "error in ProxyManager"
|
2018-06-18 12:37:58 -04:00
|
|
|
|
2018-07-04 12:59:19 -04:00
|
|
|
# TODO: better handling of status code
|
|
|
|
# see https://github.com/overleaf/write_latex/wiki/Streams-and-pipes-in-Node.js
|
|
|
|
upstream.pipe(res)
|
2018-06-18 12:37:58 -04:00
|
|
|
|
|
|
|
# make a URL from a proxy target.
|
|
|
|
# if the query is specified, set/replace the target's query with the given query
|
2018-07-04 12:59:19 -04:00
|
|
|
makeTargetUrl = (target, req) ->
|
|
|
|
targetUrl = URL.parse(parseSettingUrl(target, req))
|
|
|
|
if req.query? and Object.keys(req.query).length > 0
|
|
|
|
targetUrl.query = req.query
|
2018-06-18 12:37:58 -04:00
|
|
|
targetUrl.search = null # clear `search` as it takes precedence over `query`
|
|
|
|
targetUrl.format()
|
|
|
|
|
2018-07-04 12:59:19 -04:00
|
|
|
parseSettingUrl = (target, { params }) ->
|
2018-06-18 12:37:58 -04:00
|
|
|
return target if typeof target is 'string'
|
2018-07-04 12:59:19 -04:00
|
|
|
if typeof target.path is 'function'
|
|
|
|
path = target.path(params)
|
|
|
|
else
|
|
|
|
path = target.path
|
|
|
|
"#{target.baseUrl}#{path or ''}"
|