# Source code for cherrypy.test.test_proxy

    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 <a href='%s'>this page</a>."
                            % cherrypy.url('/this/new/page'))

                @cherrypy.expose
                @cherrypy.config(**{
                    'tools.proxy.base': None,
                })
                def base_no_base(self):
                    return cherrypy.request.base

            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 <a href='%s://www.mydomain.test" % self.scheme +
                    sn + "/this/new/page'>this page</a>.")
                self.getPage(sn + '/newurl', headers=[('X-Forwarded-Host',
                                                       'http://www.example.test')])
                self.assertBody("Browse to <a href='http://www.example.test" +
                                sn + "/this/new/page'>this page</a>.")

                # 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)

        def test_no_base_port_in_host(self):
            """
            If no base is indicated, and the host header is used to resolve
            the base, it should rely on the host header for the port also.
            """
            headers = {'Host': 'localhost:8080'}.items()
            self.getPage('/base_no_base', headers=headers)
            self.assertBody('http://localhost:8080')