I have a Flask application behind a Load balance that terminates SSL. I have code that "detects" when SSL is being used and mutates the request object:
@app.before_request
def before_request():
x_forwarded_proto = request.headers.get('X-Forwarded-Proto')
if x_forwarded_proto == 'https':
request.url = request.url.replace('http://', 'https://')
request.url_root = request.url_root.replace('http://', 'https://')
request.host_url = request.host_url.replace('http://', 'https://')
I then have a blueprint view function:
admin = Blueprint('admin', __name__, url_prefix='/admin')
@admin.route('/login')
def login():
print request.url
The output of this function is (when I go to /admin/login) is always http:// instead of https:// (even though it should have been mutated in the before_request
function.
Any ideas on how I can fix this?
To access the incoming data in Flask, you have to use the request object. The request object holds all incoming data from the request, which includes the mimetype, referrer, IP address, raw data, HTTP method, and headers, among other things.
GET and POST requestsEnter the following script in the Python shell. Once the development server is up and running, open login. html in the browser, enter the name in the text field, and then click Submit. The form data will POST to the URL in the action clause of the form label.
Turns out request
is a proxied object. I'm not sure of the internals but it's "reset" on each import. I solved the issue by subclassing Request
class ProxiedRequest(Request):
def __init__(self, environ, populate_request=True, shallow=False):
super(Request, self).__init__(environ, populate_request, shallow)
# Support SSL termination. Mutate the host_url within Flask to use https://
# if the SSL was terminated.
x_forwarded_proto = self.headers.get('X-Forwarded-Proto')
if x_forwarded_proto == 'https':
self.url = self.url.replace('http://', 'https://')
self.host_url = self.host_url.replace('http://', 'https://')
self.base_url = self.base_url.replace('http://', 'https://')
self.url_root = self.url_root.replace('http://', 'https://')
app = Flask(__name__);
app.request_class = ProxiedRequest
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With