mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #680 from sharelatex/ta-smart-proxy-take2
Replace OldAssetProxy take 2
This commit is contained in:
commit
4c6c4a2b23
4 changed files with 104 additions and 18 deletions
|
@ -1,16 +0,0 @@
|
||||||
settings = require("settings-sharelatex")
|
|
||||||
logger = require("logger-sharelatex")
|
|
||||||
request = require("request")
|
|
||||||
|
|
||||||
module.exports = (req, res, next)->
|
|
||||||
requestedUrl = req.url
|
|
||||||
|
|
||||||
redirectUrl = settings.proxyUrls[requestedUrl]
|
|
||||||
if redirectUrl?
|
|
||||||
logger.log redirectUrl:redirectUrl, reqUrl:req.url, "proxying url"
|
|
||||||
upstream = request(redirectUrl)
|
|
||||||
upstream.on "error", (error) ->
|
|
||||||
logger.error err: error, "error in OldAssetProxy"
|
|
||||||
upstream.pipe(res)
|
|
||||||
else
|
|
||||||
next()
|
|
36
services/web/app/coffee/infrastructure/ProxyManager.coffee
Normal file
36
services/web/app/coffee/infrastructure/ProxyManager.coffee
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
settings = require 'settings-sharelatex'
|
||||||
|
logger = require 'logger-sharelatex'
|
||||||
|
request = require 'request'
|
||||||
|
URL = require 'url'
|
||||||
|
|
||||||
|
module.exports = ProxyManager =
|
||||||
|
call: (req, res, next) ->
|
||||||
|
requestUrl = URL.parse(req.url)
|
||||||
|
requestPath = requestUrl.pathname # ignore the query part
|
||||||
|
|
||||||
|
target = settings.proxyUrls[requestPath]
|
||||||
|
return next() unless target? # nothing to proxy
|
||||||
|
|
||||||
|
targetUrl = makeTargetUrl(target, req.query)
|
||||||
|
logger.log targetUrl: targetUrl, reqUrl: req.url, "proxying url"
|
||||||
|
|
||||||
|
upstream = request(targetUrl)
|
||||||
|
upstream.on "error", (error) ->
|
||||||
|
logger.error err: error, "error in ProxyManager"
|
||||||
|
|
||||||
|
# TODO: better handling of status code
|
||||||
|
# see https://github.com/overleaf/write_latex/wiki/Streams-and-pipes-in-Node.js
|
||||||
|
upstream.pipe(res)
|
||||||
|
|
||||||
|
# make a URL from a proxy target.
|
||||||
|
# if the query is specified, set/replace the target's query with the given query
|
||||||
|
makeTargetUrl = (target, query) ->
|
||||||
|
targetUrl = URL.parse(parseSettingUrl(target))
|
||||||
|
if query? and Object.keys(query).length > 0
|
||||||
|
targetUrl.query = query
|
||||||
|
targetUrl.search = null # clear `search` as it takes precedence over `query`
|
||||||
|
targetUrl.format()
|
||||||
|
|
||||||
|
parseSettingUrl = (target) ->
|
||||||
|
return target if typeof target is 'string'
|
||||||
|
"#{target.baseUrl}#{target.path or ''}"
|
|
@ -32,7 +32,7 @@ Mongoose = require("./Mongoose")
|
||||||
oneDayInMilliseconds = 86400000
|
oneDayInMilliseconds = 86400000
|
||||||
ReferalConnect = require('../Features/Referal/ReferalConnect')
|
ReferalConnect = require('../Features/Referal/ReferalConnect')
|
||||||
RedirectManager = require("./RedirectManager")
|
RedirectManager = require("./RedirectManager")
|
||||||
OldAssetProxy = require("./OldAssetProxy")
|
ProxyManager = require("./ProxyManager")
|
||||||
translations = require("translations-sharelatex").setup(Settings.i18n)
|
translations = require("translations-sharelatex").setup(Settings.i18n)
|
||||||
Modules = require "./Modules"
|
Modules = require "./Modules"
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ app.use methodOverride()
|
||||||
|
|
||||||
app.use metrics.http.monitor(logger)
|
app.use metrics.http.monitor(logger)
|
||||||
app.use RedirectManager
|
app.use RedirectManager
|
||||||
app.use OldAssetProxy
|
app.use ProxyManager.call
|
||||||
|
|
||||||
|
|
||||||
webRouter.use cookieParser(Settings.security.sessionSecret)
|
webRouter.use cookieParser(Settings.security.sessionSecret)
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
sinon = require('sinon')
|
||||||
|
assertCalledWith = sinon.assert.calledWith
|
||||||
|
chai = require('chai')
|
||||||
|
should = chai.should()
|
||||||
|
expect = chai.expect
|
||||||
|
modulePath = '../../../../app/js/infrastructure/ProxyManager'
|
||||||
|
SandboxedModule = require('sandboxed-module')
|
||||||
|
MockRequest = require "../helpers/MockRequest"
|
||||||
|
MockResponse = require "../helpers/MockResponse"
|
||||||
|
|
||||||
|
describe "ProxyManager", ->
|
||||||
|
before ->
|
||||||
|
@settings = proxyUrls: {}
|
||||||
|
@request = sinon.stub().returns(
|
||||||
|
on: ()->
|
||||||
|
pipe: ()->
|
||||||
|
)
|
||||||
|
@proxyManager = SandboxedModule.require modulePath, requires:
|
||||||
|
'settings-sharelatex': @settings
|
||||||
|
'logger-sharelatex': log: ->
|
||||||
|
'request': @request
|
||||||
|
@proxyPath = '/foo/bar'
|
||||||
|
@req = new MockRequest()
|
||||||
|
@res = new MockResponse()
|
||||||
|
@next = sinon.stub()
|
||||||
|
|
||||||
|
describe 'proxyUrls', ->
|
||||||
|
beforeEach ->
|
||||||
|
@req.url = @proxyPath
|
||||||
|
@req.query = {}
|
||||||
|
@settings.proxyUrls = {}
|
||||||
|
|
||||||
|
afterEach ->
|
||||||
|
@next.reset()
|
||||||
|
@request.reset()
|
||||||
|
|
||||||
|
it 'calls next when no match', ->
|
||||||
|
@proxyManager.call(@req, @res, @next)
|
||||||
|
sinon.assert.called(@next)
|
||||||
|
sinon.assert.notCalled(@request)
|
||||||
|
|
||||||
|
it 'does not calls next when match', ->
|
||||||
|
@settings.proxyUrls[@proxyPath] = '/'
|
||||||
|
@proxyManager.call(@req, @res, @next)
|
||||||
|
sinon.assert.notCalled(@next)
|
||||||
|
sinon.assert.called(@request)
|
||||||
|
|
||||||
|
it 'proxy full URL', ->
|
||||||
|
targetUrl = 'https://user:pass@foo.bar:123/pa/th.ext?query#hash'
|
||||||
|
@settings.proxyUrls[@proxyPath] = targetUrl
|
||||||
|
@proxyManager.call(@req)
|
||||||
|
assertCalledWith(@request, targetUrl)
|
||||||
|
|
||||||
|
it 'overwrite query', ->
|
||||||
|
targetUrl = 'foo.bar/baz?query'
|
||||||
|
@req.query = { requestQuery: 'important' }
|
||||||
|
@settings.proxyUrls[@proxyPath] = targetUrl
|
||||||
|
@proxyManager.call(@req)
|
||||||
|
newTargetUrl = 'foo.bar/baz?requestQuery=important'
|
||||||
|
assertCalledWith(@request, newTargetUrl)
|
||||||
|
|
||||||
|
it 'handles target objects', ->
|
||||||
|
targetUrl = { baseUrl: 'api.v1', path: '/pa/th'}
|
||||||
|
@settings.proxyUrls[@proxyPath] = targetUrl
|
||||||
|
@proxyManager.call(@req, @res, @next)
|
||||||
|
assertCalledWith(@request, 'api.v1/pa/th')
|
Loading…
Reference in a new issue