sanic: url_for() doesn't return a working URI for a route with the trailing slash and strict_slashes=True

Describe the bug Say we have a route with the trailing slash and strict_slashes=True: @app.route('/endpoint/', strict_slashes=True) this way, url_for() will always trim the trailing slash, returning a non-working URL.

Code snippet

from sanic import Sanic
from sanic.response import html

app = Sanic()

# @app.route('/endpoint', strict_slashes=True)
@app.route('/endpoint/', strict_slashes=True)
async def endpoint(request):
    return html('OK')


@app.route('/')
async def index(request):
    # print(request.app.router.routes_all)
    return html('<a href="' + request.app.url_for('endpoint') + '">endpoint</a>')


if __name__ == '__main__':
    app.run(port=8000)

Expected behavior In my example, request.app.url_for('endpoint') is expected to return '/endpoint/'.

Environment (please complete the following information):

  • Version 0.8.3

Additional context The current implementation of url_for() just blindly removes the trailing slash, see app.py, lines 617-618.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 17 (17 by maintainers)

Most upvoted comments

@ahopkins Cool, I’ll start work on it in 3-4 days.

@MichaelYusko yeah, sort of … Busy day in here.

Also, @hatarist @ahopkins @harshanarayana take a look at the community forums for that matter.

I’ll start the discussion and post the link here ASAP …

To be honest, I was never a fan of the strict_slashes option … But I know this can lead to large discussions, so I won’t discuss that.

My only concern is that the Sanic router doesn’t actually save on Router.add the value of the strict_slashes parameter, which can be set manually (as a parameter, exactly like @hatarist example) or, if None, assume the value of app.strict_slashes, that we may not know if it was overwritten by the parameter.

IMHO, to fix this, we might need to add more complexity to the router (saving the actual value of strict_slashes to the Route namedtuple) 😬

As a matter of fact, looking closely, I don’t think the Router may even care about the strict_slashes option. I need to take a closer look at this, in the router level, to understand what this means … But this just doesn’t feels right 😐