Issue matching route with methods=['OPTIONS'] when similar route appears later using ['GET', 'POST']
daskalou opened this issue · 3 comments
With routing setup like this:
class ApiHandler:
@route_with('/<regex("(.*)"):path>', methods = ['OPTIONS'])
def cors(self, path):
# Send custom CORS headers
# This should be matched for any request
return make_response('OK', 200)
@route_with('/post/<regex("(.*)"):id>', methods = ['GET', 'POST'])
def post(self, id):
# This should only be matched on GET / POST for "/post/<id>"
return make_response('You are at the post', 200)
The cors
handler never gets run if an OPTIONS
request is made to /post/123
with the above setup.
Instead, strangely, a blank 200
reponse is returned (with no logs besides the single request entry shown in the logs).
If an OPTIONS
request is made to any other URL (or if the post
handler is commented out), the cors
handler is correctly run.
I've tried running this in multiple Flask version all the way from 1.1.4
to 3.0.1
, to no avail.
This appears to be a bug in Flask's / Werkzeug's routing.
Anyone encountered something similar or have any suggestions on what I can do to diagnose / fix?
Similar issue happened years ago, but the solution in the closed issue does not work:
What is route_with
? That's not from Flask.
What is the regex()
converter type? That's not from Flask. Other people with that type have had problems because its implementation needed to be changed for Werkzeug 3.
I used provide_automatic_options=False
and it worked as expected.
from flask import Flask
app = Flask(__name__)
@app.route("/<path:path>", methods=["OPTIONS"])
@app.route("/", methods=["OPTIONS"], defaults={"path": ""})
def handle_options(path: str) -> str:
return "options"
@app.route("/post/<int:id>", methods=["GET", "POST"], provide_automatic_options=False)
def post(id: int) -> str:
return f"post {id}"
Thanks for the quick response @davidism .
My apologies, route_with
is a decorator which in turn calls blueprint.add_url_rule()
.
regex()
is a custom routing converter, similar to:
https://gist.github.com/ekayxu/5743138
Does the fact we are calling blueprint.add_url_rule()
instead of using the @app.route
decorator increase the chance that the route is somehow handled differently when matched by Werkzeug?