Skip to content

Commit

Permalink
Merge pull request #722 from LeXofLeviafan/fix-reverse-proxy
Browse files Browse the repository at this point in the history
[#685] included flask-reverse-proxy-fix into the package
  • Loading branch information
jarun authored Mar 8, 2024
2 parents f3a5cdf + 57ddd3e commit 0e5bc21
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 16 deletions.
3 changes: 3 additions & 0 deletions bukuserver/middleware/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .flask_reverse_proxy_fix import ReverseProxyPrefixFix

__all__ = ['ReverseProxyPrefixFix']
60 changes: 60 additions & 0 deletions bukuserver/middleware/flask_reverse_proxy_fix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# clone of flask-reverse-proxy-fix with github fixes from @rachmadaniHaryono and @Glocktober

from flask import Flask as App
# noinspection PyPackageRequirements
try:
from werkzeug.contrib.fixers import ProxyFix
except ModuleNotFoundError:
from werkzeug.middleware.proxy_fix import ProxyFix


class ReverseProxyPrefixFix: # pylint: disable=too-few-public-methods
"""
Flask middleware to ensure correct URLs are generated by Flask.url_for() where an application is under a reverse
proxy. Specifically this middleware corrects URLs where a common prefix needs to be added to all URLs.
For example: If client requests for an application are reverse proxied such that:
`example.com/some-service/v1/foo` becomes `some-service-v1.internal/foo`, where `/foo` is a route within a Flask
application `foo()`.
Without this middleware, a call to `Flask.url_for('.foo')` would give: `/foo`. If returned to the client, as a
'self' link for example, this would cause a request to `example.com/foo`, which would be invalid as the
`/some-service/v1` prefix is missing.
With this middleware, a call to `Flask.url_for('.foo')` would give: '/some-service/v1/foo', which will work if used
by a client.
This middleware is compatible with both relative and absolute URLs (i.e. `Flask.url_for('.foo')` and
`Flask.url_for('.foo', _external=True)`.
This middleware incorporates the `werkzeug.contrib.fixers.ProxyFix` middleware [1] and is based on the
'Fixing SCRIPT_NAME/url_scheme when behind reverse proxy' Flask snippet [2].
Note: Ensure the prefix value includes a preceding slash, but not a trailing slash (i.e. use `/foo` not `/foo/`).
[1] http://werkzeug.pocoo.org/docs/0.14/contrib/fixers/#werkzeug.contrib.fixers.ProxyFix
[2] http://flask.pocoo.org/snippets/35/
"""
def __init__(self, app: App, **kwargs):
"""
:type app: App
:param app: Flask application
"""
self.app = app.wsgi_app
self.prefix = None

if 'REVERSE_PROXY_PATH' in app.config:
self.prefix = app.config['REVERSE_PROXY_PATH']

self.app = ProxyFix(self.app, **kwargs)

app.wsgi_app = self

def __call__(self, environ, start_response):
if self.prefix is not None:
environ['SCRIPT_NAME'] = self.prefix
path_info = environ['PATH_INFO']
if path_info.startswith(self.prefix):
environ['PATH_INFO'] = path_info[len(self.prefix):]

return self.app(environ, start_response)
1 change: 0 additions & 1 deletion bukuserver/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ Flask-Admin>=1.6.1
Flask-API>=3.0.post1
Flask-Bootstrap>=3.3.7.1
flask-paginate>=2022.1.8
flask-reverse-proxy-fix @ https://github.com/rachmadaniHaryono/flask-reverse-proxy-fix/archive/refs/tags/v0.2.3.zip
Flask-WTF>=1.0.1
Flask>=2.2.2,<2.3
werkzeug<2.4
9 changes: 3 additions & 6 deletions bukuserver/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
from buku import BukuDb, __version__, network_handler

try:
from flask_reverse_proxy_fix.middleware import ReverseProxyPrefixFix
from .middleware import ReverseProxyPrefixFix
except ImportError:
ReverseProxyPrefixFix = None
from bukuserver.middleware import ReverseProxyPrefixFix
import click
import flask
from flask import __version__ as flask_version # type: ignore
Expand Down Expand Up @@ -99,10 +99,7 @@ def create_app(db_file=None):
if reverse_proxy_path.endswith('/'):
print('Warning: reverse proxy path should not include trailing slash')
app.config['REVERSE_PROXY_PATH'] = reverse_proxy_path
if ReverseProxyPrefixFix:
ReverseProxyPrefixFix(app)
else:
raise ImportError('Failed to import ReverseProxyPrefixFix')
ReverseProxyPrefixFix(app)
bukudb = BukuDb(dbfile=app.config['BUKUSERVER_DB_FILE'])
app.config['FLASK_ADMIN_SWATCH'] = (os.getenv('BUKUSERVER_THEME') or 'default').lower()
app.config['BUKUSERVER_LOCALE'] = os.getenv('BUKUSERVER_LOCALE') or 'en'
Expand Down
10 changes: 1 addition & 9 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,6 @@
"Flask>=2.2.2,<2.3",
"werkzeug<2.4",
]
reverse_proxy = " ".join(
[
"flask-reverse-proxy-fix",
"@",
"https://github.com/rachmadaniHaryono/flask-reverse-proxy-fix/archive/refs/tags/v0.2.3.zip",
]
)
install_requires = [
'beautifulsoup4>=4.4.1',
'certifi',
Expand Down Expand Up @@ -82,9 +75,8 @@
'console_scripts': ['buku=buku:main', 'bukuserver=bukuserver.server:cli']
},
extras_require={
"tests": tests_require + server_require + [reverse_proxy],
"tests": tests_require + server_require,
"server": server_require,
"reverse_proxy": [reverse_proxy],
"docs": [
"myst-parser>=0.17.0",
"sphinx-rtd-theme>=1.0.0",
Expand Down
1 change: 1 addition & 0 deletions tests/.pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
disable=
assigning-non-slot,
broad-except,
c-extension-no-member,
consider-using-f-string,
consider-using-with,
dangerous-default-value,
Expand Down

0 comments on commit 0e5bc21

Please sign in to comment.