import cherrypy from cherrypy.test import helper script_names = ['', '/path/to/myapp'] class ProxyTest(helper.CPWebCase): @staticmethod def setup_server(): # Set up site cherrypy.config.update({ 'tools.proxy.on': True, 'tools.proxy.base': 'www.mydomain.test', }) # Set up application class Root: def __init__(self, sn): # Calculate a URL outside of any requests. self.thisnewpage = cherrypy.url( '/this/new/page', script_name=sn) @cherrypy.expose def pageurl(self): return self.thisnewpage @cherrypy.expose def index(self): raise cherrypy.HTTPRedirect('dummy') @cherrypy.expose def remoteip(self): return cherrypy.request.remote.ip @cherrypy.expose @cherrypy.config(**{ 'tools.proxy.local': 'X-Host', 'tools.trailing_slash.extra': True, }) def xhost(self): raise cherrypy.HTTPRedirect('blah') @cherrypy.expose def base(self): return cherrypy.request.base @cherrypy.expose @cherrypy.config(**{'tools.proxy.scheme': 'X-Forwarded-Ssl'}) def ssl(self): return cherrypy.request.base @cherrypy.expose def newurl(self): return ("Browse to this page." % cherrypy.url('/this/new/page')) for sn in script_names: cherrypy.tree.mount(Root(sn), sn) def testProxy(self): self.getPage('/') self.assertHeader('Location', '%s://www.mydomain.test%s/dummy' % (self.scheme, self.prefix())) # Test X-Forwarded-Host (Apache 1.3.33+ and Apache 2) self.getPage( '/', headers=[('X-Forwarded-Host', 'http://www.example.test')]) self.assertHeader('Location', 'http://www.example.test/dummy') self.getPage('/', headers=[('X-Forwarded-Host', 'www.example.test')]) self.assertHeader('Location', '%s://www.example.test/dummy' % self.scheme) # Test multiple X-Forwarded-Host headers self.getPage('/', headers=[ ('X-Forwarded-Host', 'http://www.example.test, www.cherrypy.test'), ]) self.assertHeader('Location', 'http://www.example.test/dummy') # Test X-Forwarded-For (Apache2) self.getPage('/remoteip', headers=[('X-Forwarded-For', '192.168.0.20')]) self.assertBody('192.168.0.20') # Fix bug #1268 self.getPage('/remoteip', headers=[ ('X-Forwarded-For', '67.15.36.43, 192.168.0.20') ]) self.assertBody('67.15.36.43') # Test X-Host (lighttpd; see https://trac.lighttpd.net/trac/ticket/418) self.getPage('/xhost', headers=[('X-Host', 'www.example.test')]) self.assertHeader('Location', '%s://www.example.test/blah' % self.scheme) # Test X-Forwarded-Proto (lighttpd) self.getPage('/base', headers=[('X-Forwarded-Proto', 'https')]) self.assertBody('https://www.mydomain.test') # Test X-Forwarded-Ssl (webfaction?) self.getPage('/ssl', headers=[('X-Forwarded-Ssl', 'on')]) self.assertBody('https://www.mydomain.test') # Test cherrypy.url() for sn in script_names: # Test the value inside requests self.getPage(sn + '/newurl') self.assertBody( "Browse to this page.") self.getPage(sn + '/newurl', headers=[('X-Forwarded-Host', 'http://www.example.test')]) self.assertBody("Browse to this page.") # Test the value outside requests port = '' if self.scheme == 'http' and self.PORT != 80: port = ':%s' % self.PORT elif self.scheme == 'https' and self.PORT != 443: port = ':%s' % self.PORT host = self.HOST if host in ('0.0.0.0', '::'): import socket host = socket.gethostname() expected = ('%s://%s%s%s/this/new/page' % (self.scheme, host, port, sn)) self.getPage(sn + '/pageurl') self.assertBody(expected) # Test trailing slash (see # https://github.com/cherrypy/cherrypy/issues/562). self.getPage('/xhost/', headers=[('X-Host', 'www.example.test')]) self.assertHeader('Location', '%s://www.example.test/xhost' % self.scheme)