aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJocelyn Delande <jocelyn@crapouillou.net>2015-08-19 22:47:52 +0200
committerJocelyn Delande <jocelyn@crapouillou.net>2015-08-19 22:56:45 +0200
commit15091e28c070dc0d248b310fe1aa9638de92424a (patch)
tree9e0bcca70cd79dbdd8722bfc6937d97cd476aa09
parentd6c514e7d176fcdf6be3e3ca6eb05ea2ea725d71 (diff)
downloadihatemoney-mirror-15091e28c070dc0d248b310fe1aa9638de92424a.zip
ihatemoney-mirror-15091e28c070dc0d248b310fe1aa9638de92424a.tar.gz
ihatemoney-mirror-15091e28c070dc0d248b310fe1aa9638de92424a.tar.bz2
Made an URL prefix configurable in settings, includes tests.
-rw-r--r--README.rst7
-rw-r--r--budget/default_settings.py1
-rw-r--r--budget/run.py3
-rw-r--r--budget/tests.py15
-rw-r--r--budget/utils.py31
5 files changed, 55 insertions, 2 deletions
diff --git a/README.rst b/README.rst
index 80e2fb0..6923a83 100644
--- a/README.rst
+++ b/README.rst
@@ -48,7 +48,12 @@ To deploy it, I'm using gunicorn and supervisord::
Don't forget to set the right permission for your files !
Also, create a `settings.py` file with the appropriate values if you need to
-use a different database for instance.
+use a different database for instance. You can also set `APPLICATION_ROOT` if
+you want to prefix your URLs to serve ihatemonney in the *folder* of a domain,
+e.g:
+
+ APPLICATION_ROOT='/budget'
+
How about the REST API?
=======================
diff --git a/budget/default_settings.py b/budget/default_settings.py
index 394ab00..c80c783 100644
--- a/budget/default_settings.py
+++ b/budget/default_settings.py
@@ -4,6 +4,7 @@ SQLACHEMY_ECHO = DEBUG
SECRET_KEY = "tralala"
MAIL_DEFAULT_SENDER = ("Budget manager", "budget@notmyidea.org")
+APPLICATION_ROOT = '/'
try:
from settings import *
diff --git a/budget/run.py b/budget/run.py
index 2e18599..bdb8f46 100644
--- a/budget/run.py
+++ b/budget/run.py
@@ -6,7 +6,7 @@ from raven.contrib.flask import Sentry
from web import main, db, mail
from api import api
-
+from utils import PrefixedWSGI
app = Flask(__name__)
@@ -15,6 +15,7 @@ def configure():
""" A way to (re)configure the app, specially reset the settings
"""
app.config.from_object("default_settings")
+ app.wsgi_app = PrefixedWSGI(app)
# Deprecations
if 'DEFAULT_MAIL_SENDER' in app.config:
diff --git a/budget/tests.py b/budget/tests.py
index 0f7c2a2..b151e7f 100644
--- a/budget/tests.py
+++ b/budget/tests.py
@@ -821,5 +821,20 @@ class APITestCase(TestCase):
self.assertStatus(404, req)
+class ServerTestCase(APITestCase):
+ def setUp(self):
+ run.configure()
+ super(ServerTestCase, self).setUp()
+
+ def test_unprefixed(self):
+ req = self.app.get("/foo/")
+ self.assertStatus(303, req)
+
+ def test_prefixed(self):
+ run.app.config['APPLICATION_ROOT'] = '/foo'
+ req = self.app.get("/foo/")
+ self.assertStatus(200, req)
+
+
if __name__ == "__main__":
unittest.main()
diff --git a/budget/utils.py b/budget/utils.py
index 60337fb..7717aaa 100644
--- a/budget/utils.py
+++ b/budget/utils.py
@@ -32,3 +32,34 @@ class Redirect303(HTTPException, RoutingException):
def get_response(self, environ):
return redirect(self.new_url, 303)
+
+
+class PrefixedWSGI(object):
+ '''
+ Wrap the application in this middleware and configure the
+ front-end server to add these headers, to let you quietly bind
+ this to a URL other than / and to an HTTP scheme that is
+ different than what is used locally.
+
+ It relies on "APPLICATION_ROOT" app setting.
+
+ Inspired from http://flask.pocoo.org/snippets/35/
+
+ :param app: the WSGI application
+ '''
+ def __init__(self, app):
+ self.app = app
+ self.wsgi_app = app.wsgi_app
+
+ def __call__(self, environ, start_response):
+ script_name = self.app.config['APPLICATION_ROOT']
+ if script_name:
+ environ['SCRIPT_NAME'] = script_name
+ path_info = environ['PATH_INFO']
+ if path_info.startswith(script_name):
+ environ['PATH_INFO'] = path_info[len(script_name):]
+
+ scheme = environ.get('HTTP_X_SCHEME', '')
+ if scheme:
+ environ['wsgi.url_scheme'] = scheme
+ return self.wsgi_app(environ, start_response)