Search code examples
pythonflaskurl-routingwerkzeug

Flask redirecting requests to urls containing '@'


I am re-implementing a legacy system as a Flask app and must keep url patterns as they are. One of the urls includes a user's full email address directly (in other words, the email address is part of the url and not as a GET parameter).

When I send requests to this url, Flask automatically responds with a redirect to the same url except that the '@' sign in the email address is replaced with '%40'. For example, a request to /users/new/user@example.com/ is redirected to /users/new/user%40example.com/. I even receive this response from Flask when I send up POST requests directly to the second url, so I'm assuming that the '%40' is automatically translated into an '@' character when processed for the request.

How do I get Flask to accept requests to urls that include the '@' sign without redirecting? This may be Werkzeug's fault, as Flask's URL resolving system is built on Werkzeug.

EDIT: I Incorrectly included a trailing slash in the initial request URL listed in this question. My problem was in fact caused by the absence of the slash, not the replacement of '@' with '%40'.


Solution

  • It turns out that 9000 was right: the '@' sign is a perfectly legal character in the URL. As such, that shouldn't be what Flask was complaining about. Much less obvious than the conversion of '@' to '%40' in the redirected URL is that the trailing slash was missing from the initial request. When writing my question, I was so focused on the change from '@' to '%40' (which is, as it turns out, the same thing in URL terms) that I didn't notice the missing trailing slash at the end of the first URL and mistakenly included it when writing this question.

    Adding the trailing slash to the POST URL, regardless of whether that URL contained '@' or '%40', fixed the issue. If Flask replaces '@' with '%40' when redirecting, that is nothing to worry about. The real problem is likely caused by something else entirely.