title: Forcing use of HTTPS with Flask's before_request()
body: <p>I'm writing an app for IBM's Bluemix using Python Flask. I want to force inbound requests to be https. This bit of code works:</p>
  
  <pre><code># We want to redirect the request to use https. X-Forwarded-Proto is only set in Bluemix runtime. 
  forwarded_protocol = request.headers.get('X-Forwarded-Proto', None)
  if forwarded_protocol is not None:
      if forwarded_protocol == 'http':
          new_url = request.url.replace('http', 'https', 1)
          return redirect(new_url)
  </code></pre>
  
  <p>Instead of putting it in each of my route definitions, I'd like to do it in one place. Based on Flask documentation, I think what I want is to use <code>before_request()</code>.</p>
  
  <p>The Flask documentation states:</p>
  
  <blockquote>
    <p>The function will be called without any arguments. If the function returns a non-None value, it’s handled as if it was the return value from the view and further request handling is stopped.</p>
  </blockquote>
  
  <p>I think this implies that if I return <code>None</code> that processing will continue with the route code for the request. So my implementation would look like:</p>
  
  <pre><code>@app.before_request
  def force_https():
      # We want to redirect the request to use https. X-Forwarded-Proto is only set in Bluemix runtime. 
      try:
          forwarded_protocol = request.headers.get('X-Forwarded-Proto', None)
          if forwarded_protocol is not None:
              if forwarded_protocol == 'http':
                  new_url = request.url.replace('http', 'https', 1)
                  return redirect(new_url)
              else:
                  return None
          else:
              return None
      except RuntimeError as e:
          return None
  </code></pre>
  
  <p>It's clear though that either my implementation or understanding are off. I'm not able to ever hand off control after this method runs to the route code. And <code>before_request()</code> also appears to be called as Flask is starting up, before the first request, hence the <code>try/except</code> block. Is my failure a problem with my implementation, understanding of Flask, both?</p>