Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

modify flask url before routing

My Flask app has url routing defined as

self.add_url_rule('/api/1/accounts/<id_>', view_func=self.accounts, methods=['GET'])

Problem is one of the application making queries to this app adds additional / in url like /api/1//accounts/id. It's not in my control to correct the application which makes such queries so I cant change it.

To resolve this problem currently I have added multiple rules

self.add_url_rule('/api/1/accounts/<id_>', view_func=self.accounts, methods=['GET'])
self.add_url_rule('/api/1//accounts/<id_>', view_func=self.accounts, methods=['GET'])

There are number of such routes and it's ugly workaround. Is there a way in flask to modify URL before it hits the routing logic?

like image 212
shrishinde Avatar asked Jun 20 '17 11:06

shrishinde


1 Answers

I'd normalise the path before it gets to Flask, either by having the HTTP server that hosts the WSGI container or a proxy server that sits before your stack do this, or by using WSGI middleware.

The latter is easily written:

import re
from functools import partial


class PathNormaliser(object):
    _collapse_slashes = partial(re.compile(r'/+').sub, r'/')

    def __init__(self, application):
        self.application = application

    def __call__(self, env, start_response):    
        env['PATH_INFO'] = self._collapse_slashes(env['PATH_INFO'])                                                                                                  
        return self.application(env, start_response)

You may want to log that you are applying this transformation, together with diagnostic information like the REMOTE_HOST and HTTP_USER_AGENT entries. Personally, I'd force that specific application to generate non-broken URLs as soon as possible.

Look at your WSGI server documentation to see how to add in extra WSGI middleware components.

like image 64
Martijn Pieters Avatar answered Oct 07 '22 20:10

Martijn Pieters