title: Flask app hosted by CherryPy: OPTIONS returns 404
body: <p>I have a restful API created using Flask and Flask-Restful. Everything works fine using the development server. All routes are in a Blueprint, though the particular route we're dealing with here is not a Flask-Restful one. It's just a normal Flask route.</p>
  
  <p>I am also using Flask-CORS.</p>
  
  <p>To deploy, everything is dockerized and I'm using CherryPy as the WSGI host. So a CherryPy app hosts the Flask app in a container.
  I'm using Traefik as a reverse proxy in another container.</p>
  
  <p>If I make the following request in Chrome by pasting the URL in, the GET request works:</p>
  
  <pre><code>https://api.my-app.new/api/admin/user?_end=10&amp;_order=DESC&amp;_sort=id&amp;_start=0
  </code></pre>
  
  <p>However, if I attemtp to make the same GET request from a React app, an OPTIONS preflight request is made and it is failing with a 404.
  I've traced through it as best I can in PyCharm and the problem seems to be in the following code in Flask's app.py:</p>
  
  <pre><code>def preprocess_request(self):
      bp = _request_ctx_stack.top.request.blueprint
  </code></pre>
  
  <p>Basically, the blueprint is not found.</p>
  
  <p>What is actually getting sent is seen in this curl call:</p>
  
  <pre><code>curl 'https://api.my-app.new/api/admin/user?_end=10&amp;_order=DESC&amp;_sort=id&amp;_start=0' \
       -X OPTIONS -H 'access-control-request-method: GET' -H 'origin: https://admin.my-app.new' \
       -H 'accept-encoding: gzip, deflate, br' -H 'accept-language: en-US,en;q=0.9' \
       -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36' \
       -H 'accept: */*' -H 'referer: https://admin.my-app.new/' -H 'authority: api.my-app.new' \
       -H 'access-control-request-headers: authorization,content-type' --compressed
  </code></pre>
  
  <p>And if I print out the headers received by the Flask-app (in @app.before_request), I get the following:</p>
  
  <pre><code>[2018-01-25 04:31:48,438] INFO - X-Forwarded-Server: cb5d56692c6d
  Referer: https://admin.my-app.new/
  Accept-Language: en-US,en;q=0.9
  Origin: https://admin.my-app.new
  X-Real-Ip: 172.19.0.1
  User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
  Access-Control-Request-Headers: authorization,content-type
  X-Forwarded-Proto: https
  Host: api.my-app.new
  Accept: */*
  Access-Control-Request-Method: GET
  X-Forwarded-Host: api.my-app.new
  X-Forwarded-For: 172.19.0.1
  X-Forwarded-Port: 443
  Accept-Encoding: gzip, deflate, br
  
  [2018-01-25 04:31:48,440] INFO - Error 404:/api/admin/user?_end=10&amp;_order=DESC&amp;_sort=id&amp;_start=0: 404 Not Found: The requested URL was not found on the server.  If you entered the URL manually please check your spelling and try again. ("/app/app/routes.py:87")
  </code></pre>
  
  <p>Now, if I make the same request with the app running without the traefik reverse proxy, it works. The only thing that is different in the curl
  request is that I'm using http, instead of https.</p>
  
  <p>Here are the headers that Flask receives in this case:</p>
  
  <pre><code>[2018-01-24 21:43:43,199] INFO - Referer: https://admin.my-app.new/
  Origin: https://admin.my-app.new
  User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
  Authority: api.my-app.new
  Access-Control-Request-Headers: authorization,content-type
  Host: api.my-app.new:8000
  Accept: */*
  Access-Control-Request-Method: GET
  Accept-Language: en-US,en;q=0.9
  Accept-Encoding: gzip, deflate, br
  
  [24/Jan/2018 21:43:43] "OPTIONS /api/admin/user?_end=10&amp;_order=DESC&amp;_sort=id&amp;_start=0 HTTP/1.1" 200 -
  </code></pre>
  
  <p>I figure that there is something wrong with the headers or something that is confusing Flask. I saw another post from 2014 that mentioned needing the SERVER_NAME, but that didn't help.</p>
  
  <p>Finally, I had originally used NGinx as a reserve proxy and had gotten everything working. One of the the things
  that was hard to get working with NGinx was redirects and OPTION requests. I did get it working after madly chasing down various blog 
  posts, but as I look back on it as I right this, I notice a curious thing: I wound up writing script in nginx.conf
  to automatically return 200 for all OPTIONS requests!</p>
  
  <p>Any idea why the OPTION requests are failing?</p>