From 1cf582e866edb4981f9fbeee5ca47ef6206e55de Mon Sep 17 00:00:00 2001 From: Ralph Bean Date: Fri, 24 Feb 2017 10:23:35 -0500 Subject: [PATCH] Allow MBS to run behind a reverse proxy. This fixes #352. --- module_build_service/__init__.py | 2 ++ module_build_service/proxy.py | 59 ++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 module_build_service/proxy.py diff --git a/module_build_service/__init__.py b/module_build_service/__init__.py index c39c3072..412393ac 100644 --- a/module_build_service/__init__.py +++ b/module_build_service/__init__.py @@ -50,8 +50,10 @@ from module_build_service.errors import ( ValidationError, Unauthorized, UnprocessableEntity, Conflict, NotFound, Forbidden, json_error) from module_build_service.config import init_config +from module_build_service.proxy import ReverseProxy app = Flask(__name__) +app.wsgi_app = ReverseProxy(app.wsgi_app) conf = init_config(app) diff --git a/module_build_service/proxy.py b/module_build_service/proxy.py new file mode 100644 index 00000000..0b753514 --- /dev/null +++ b/module_build_service/proxy.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2017 Red Hat, Inc. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# +# Written by Ralph Bean + +""" +Allows MBS to run behind reverse proxy and to ensure redirects work with https. + +WSGI Middleware!! + +Source: http://flask.pocoo.org/snippets/35/ by Peter Hansen +""" + + +class ReverseProxy(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. + + :param app: the WSGI application + ''' + def __init__(self, app): + self.app = app + + def __call__(self, environ, start_response): + script_name = environ.get('HTTP_X_SCRIPT_NAME', '') + 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):] + + server = environ.get('HTTP_X_FORWARDED_HOST', '') + if server: + environ['HTTP_HOST'] = server + + scheme = environ.get('HTTP_X_SCHEME', '') + if scheme: + environ['wsgi.url_scheme'] = scheme + return self.app(environ, start_response)