Merge "Add support for custom context/application root"

This commit is contained in:
Zuul 2018-05-01 19:06:32 +00:00 committed by Gerrit Code Review
commit 41427039de
4 changed files with 63 additions and 0 deletions

View File

@ -39,6 +39,11 @@ class BaseConfig(object):
True,
value_type='boolean'
)
self.APPLICATION_ROOT = ara_config(
'application_root',
'ARA_APPLICATION_ROOT',
'/'
)
self.SQLALCHEMY_DATABASE_URI = self.ARA_DATABASE
self.SQLALCHEMY_TRACK_MODIFICATIONS = False
self.SQLALCHEMY_ECHO = ara_config(

View File

@ -41,6 +41,7 @@ class TestConfig(TestAra):
'FREEZER_IGNORE_404_NOT_FOUND': True,
'ARA_DIR': os.path.expanduser('~/.ara'),
'SQLALCHEMY_DATABASE_URI': db,
'APPLICATION_ROOT': '/',
'ARA_HOST': '127.0.0.1',
'ARA_AUTOCREATE_DATABASE': True,
'ARA_PORT': "9191",

View File

@ -62,6 +62,7 @@ def create_app():
configure_app(app)
configure_dirs(app)
configure_logging(app)
configure_app_root(app)
configure_blueprints(app)
configure_static_route(app)
configure_db(app)
@ -88,6 +89,14 @@ def configure_logging(app):
setup_logging(app.config)
def configure_app_root(app):
log = logging.getLogger('ara.webapp.configure_app_root')
# Don't load the middleware needlessly if the root is actually '/'
if app.config['APPLICATION_ROOT'] != '/':
app.wsgi_app = AppRootMiddleware(app, app.wsgi_app)
log.debug('Application root loaded: %s' % app.config['APPLICATION_ROOT'])
def configure_errorhandlers(app):
@app.errorhandler(404)
def page_not_found(error):
@ -309,3 +318,37 @@ def configure_cache(app):
if not getattr(app, '_cache', None):
app._cache = {}
class AppRootMiddleware(object):
"""
Middleware to manage route prefixes, for example when hosting ARA in a
subdirectory.
"""
def __init__(self, app, wsgi_app):
self.log = logging.getLogger('ara.webapp.AppRootMiddleware')
self.log.debug('Initializing AppRootMiddleware')
self.app = app
self.wsgi_app = wsgi_app
def __call__(self, environ, start_response):
root = self.app.config['APPLICATION_ROOT']
if environ['PATH_INFO'].startswith(root):
environ['PATH_INFO'] = environ['PATH_INFO'][len(root):]
environ['SCRIPT_NAME'] = root
self.log.debug('Returning with root %s' % root)
return self.wsgi_app(environ, start_response)
else:
self.log.debug('Returning 404 for %s' % environ['PATH_INFO'])
url = "{scheme}://{host}{root}".format(
scheme=environ['wsgi.url_scheme'],
host=environ['HTTP_HOST'],
root=root,
)
msg = """
This URL doesn't belong to an ARA application. <br />
<br />
Did you mean to browse to <a href='{url}'>{url}</a> instead ?
""".format(url=url)
start_response('404', [('Content-Type', 'text/html')])
return [msg.strip().encode()]

View File

@ -117,6 +117,8 @@ Parameters and their defaults
+-------------------------------+----------------------------+-------------------------------------------+
| ARA_PORT_ | port | 9191 |
+-------------------------------+----------------------------+-------------------------------------------+
| ARA_APPLICATION_ROOT_ | application_root | / |
+-------------------------------+----------------------------+-------------------------------------------+
| ARA_LOG_CONFIG_ | logconfig | None |
+-------------------------------+----------------------------+-------------------------------------------+
| ARA_LOG_FILE_ | logfile | ~/.ara/ara.log |
@ -237,6 +239,18 @@ the ``ara-manage runserver`` command.
It is equivalent to the ``-p`` or ``--port`` argument of the
``ara-manage runserver`` command.
ARA_APPLICATION_ROOT
~~~~~~~~~~~~~~~~~~~~
The path at which the web application should be loaded.
The default behavior is to load the application at the root (``/``) of your
host.
Change this parameter if you'd like to host your application elsewhere.
For example, ``/ara`` would make the application available under
``http://host/ara`` instead of ``http://host/``.
ARA_LOG_CONFIG
~~~~~~~~~~~~~~