librelist archives

« back to archive

Flask exposes file system path when redirecting to add a trailing slash?

Flask exposes file system path when redirecting to add a trailing slash?

From:
Chris Peterson
Date:
2011-05-04 @ 23:33
When Flask redirects to add a trailing slash to a URL, the new URL
exposes the script's file system path, not the "logical" pretty URL.

My mod_rewrite rules map "http://example.com/whatever" to be processed
(invisibly) by my CGI script "http://example.com/dispatch.cgi". But
when Flask redirects to add a trailing slash,
"http://example.com/add_slash" becomes
"http://example.com/dispatch.cgi/add_slash/" in the user's browser
window!

Is there a way to preserve the original "logical" URL (without or with
the trailing slash)? Setting "app.url_map.strict_slashes = False" does
not seem to alter the redirect behavior.


Here is some example code. Assume my Flask app looks like this:

    @route('/add_slash/')
    def hello_add_slash():
        return 'Hello add_slash'

    @route('/no_slash')
    def hello_no_slash():
        return 'Hello no_slash'


This code gives the following test results:

* HAPPY "http://example.com/add_slash/" loads the page correctly.
* SAD: "http://example.com/add_slash" redirects to the ugly URL
"http://example.com/dispatch.cgi/add_slash/" (but displays the page
correctly).
* HAPPY: "http://example.com/no_slash" loads the page correctly.
* HAPPY: "http://example.com/no_slash/" 404s but this is the expected behavior.


thanks!
chris

Re: [flask] Flask exposes file system path when redirecting to add a trailing slash?

From:
Armin Ronacher
Date:
2011-05-05 @ 10:03
Hi,

On 2011-05-05 1:33 AM, Chris Peterson wrote:
> When Flask redirects to add a trailing slash to a URL, the new URL
> exposes the script's file system path, not the "logical" pretty URL.
>
> My mod_rewrite rules map "http://example.com/whatever" to be processed
> (invisibly) by my CGI script "http://example.com/dispatch.cgi". But
> when Flask redirects to add a trailing slash,
> "http://example.com/add_slash" becomes
> "http://example.com/dispatch.cgi/add_slash/" in the user's browser
> window!
mod_rewrite is an apache hack that is not transparent to Flask.  You 
will need an additional middleware that tells Flask about the changed path:

     class PathStrippingMiddleware(object):
         def __init__(self, app):
             self.app = app
         def __call__(self, environ, start_response):
             environ['SCRIPT_NAME'] = ''
             return self.app(environ, start_response)

     app.wsgi_app = PathStrippingMiddleware(app.wsgi_app)


Regards,
Armin

Re: [flask] Flask exposes file system path when redirecting to add a trailing slash?

From:
Chris Peterson
Date:
2011-05-06 @ 06:22
Thank you, Armin! That fixed my problem.

And just to be thorough: my actual URL was in a deeper directory like
"http://example.com/test/dispatch.fcgi". So SCRIPT_NAME was
"/test/dispatch.cgi". But since I wanted to hide just the dispatch.cgi
filename and preserve the "/test/" directory, I modified your example
code like this:


    def __call__(self, environ, start_response):
        environ['SCRIPT_NAME'] = environ['SCRIPT_NAME'].rstrip('dispatch.fcgi')
        return self.app(environ, start_response)


thanks!
chris



On Thu, May 5, 2011 at 3:03 AM, Armin Ronacher
<armin.ronacher@active-4.com> wrote:
> Hi,
>
> On 2011-05-05 1:33 AM, Chris Peterson wrote:
>> When Flask redirects to add a trailing slash to a URL, the new URL
>> exposes the script's file system path, not the "logical" pretty URL.
>>
>> My mod_rewrite rules map "http://example.com/whatever" to be processed
>> (invisibly) by my CGI script "http://example.com/dispatch.cgi". But
>> when Flask redirects to add a trailing slash,
>> "http://example.com/add_slash" becomes
>> "http://example.com/dispatch.cgi/add_slash/" in the user's browser
>> window!
> mod_rewrite is an apache hack that is not transparent to Flask.  You
> will need an additional middleware that tells Flask about the changed path:
>
>     class PathStrippingMiddleware(object):
>         def __init__(self, app):
>             self.app = app
>         def __call__(self, environ, start_response):
>             environ['SCRIPT_NAME'] = ''
>             return self.app(environ, start_response)
>
>     app.wsgi_app = PathStrippingMiddleware(app.wsgi_app)
>
>
> Regards,
> Armin
>