arielCo
arielCo

Reputation: 431

Flask adds trailing slash to URL, no routes match

As per the title, Apache 2.4 seems to be appending '/' to the URL (according to request.url) and Flask's routes don't match with or without it.

(relevant) File structure

/var/www/wsgi
...
├── dizmo
│   └── __init__.py
├── foo.wsgi
├── hello1.wsgi
└── __pycache__
    └── adapter.cpython-35.pyc

foo.wsgi

import sys
import inspect
sys.path.append('/var/www/wsgi')
from dizmo import app as application

dizmo/__init__.py

from flask import Flask, request
import inspect
import sys

app = Flask(__name__)
app.debug = True
print( "app.config['SERVER_NAME']={}".format(app.config['SERVER_NAME']) )
print("{}:{} (outside)".format( inspect.currentframe().f_code.co_filename, inspect.currentframe().f_lineno ) )

@app.route('/foo')
@app.route('/foo/')
def tattletale():
    return 'I\'m foo'

@app.errorhandler(404)
def err_handler_404(error):
    return '{}: no route'.format(request.url), 404

mysite.conf

<VirtualHost *:9000>
    <Directory /var/www/wsgi>
        Require all granted
        DirectorySlash Off
    </Directory>

    WSGIDaemonProcess CDRDB processes=2 threads=15 display-name=%{GROUP} python-path=/var/www/python-packages
    WSGIProcessGroup CDRDB
    WSGIScriptReloading On
    WSGIScriptAlias /foo /var/www/wsgi/foo.wsgi
    WSGIScriptAlias /hello1 /var/www/wsgi/hello1.wsgi
</VirtualHost>

When it runs:

curl http://127.0.0.1:9000/foo
http://127.0.0.1:9000/foo/: no route

Notice the trailing slash in request.url.

I went through two dozen posts here and on Reddit regarding routes before I added the 404 handler, and now I'm at the end of my wits/rope. There's no 'foo' directory so DirectorySlash shouldn't even matter.

Edit: strict_slashes=False doesn't seem to change anything, as well as using a single decorator, /foo or /foo/.

Edit 2: Apparently, Apache or mod_wsgi plays tricks with the path, and /foo/foo somehow works. The Flask standalone server works as expected:

curl http://127.0.0.1:9000/foo/foo  # Apache
I'm foo. route=http://127.0.0.1:9000/foo/foo

curl http://127.0.0.1:5000/foo      # flask run
I'm foo. route=http://127.0.0.1:5000/foo

--

>>> flask.__version__
'0.12.2'
>>> sys.version_info
sys.version_info(major=3, minor=5, micro=2, releaselevel='final', serial=0)
$ apachectl -v
Server version: Apache/2.4.18 (Ubuntu)
Server built:   2017-09-18T15:09:02

Upvotes: 1

Views: 2396

Answers (3)

Smit Mehta
Smit Mehta

Reputation: 101

You did not need to specify the slash in the second decorator the flask is automatically redirect to that controller associated with your url

I also suggest you to remove the second decorator...

Upvotes: 0

sytech
sytech

Reputation: 40921

Your WSGIScriptAlias is misconfigured. Your app is being served by Apache relative to /foo

To get the behavior you want, the alias should be for the root directory, I.E. / instead of /foo

Upvotes: 3

Giacomo Catenazzi
Giacomo Catenazzi

Reputation: 9523

You should use only one decorator between

@app.route('/foo')
@app.route('/foo/')

The second decorator causes also the redirect with final slash.

Upvotes: 0

Related Questions