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
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
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
>