summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbbangert <none@none>2006-11-07 17:04:22 -0800
committerbbangert <none@none>2006-11-07 17:04:22 -0800
commit787c16cb10826f3a7951a6195422cf129a5037ef (patch)
treef8f6a3a138ed79f8c8531b467c1da60b158d7f50
parente6253c47450b956050c655c95566d5bd15ead1ac (diff)
downloadroutes-787c16cb10826f3a7951a6195422cf129a5037ef.tar.gz
[svn] Initial commit of wsgi middleware using routes and new wsgiorg.routing_args spec.
--HG-- branch : trunk
-rw-r--r--CHANGELOG4
-rw-r--r--routes/middleware.py80
-rw-r--r--setup.py2
3 files changed, 84 insertions, 2 deletions
diff --git a/CHANGELOG b/CHANGELOG
index d792a06..5db827e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,7 +1,9 @@
Routes Changelog
========================
--- 1.5.3 (**svn**)
+-- 1.6 (**svn**)
+* Added WSGI middleware that does route resolving using new `WSGI.org Routing
+ Vars Spec <http://wsgi.org/wsgi/Specifications/routing_args>`_.
* Added _absolute keyword option route connect to ignore SCRIPT_NAME settings.
Suggested by Ian Bicking.
diff --git a/routes/middleware.py b/routes/middleware.py
new file mode 100644
index 0000000..96292b7
--- /dev/null
+++ b/routes/middleware.py
@@ -0,0 +1,80 @@
+"""Routes WSGI Middleware"""
+import re
+import urllib
+
+try:
+ from paste.wsgiwrappers import WSGIRequest
+except:
+ pass
+
+from routes.base import request_config
+
+class RoutesMiddleware(object):
+ def __init__(self, wsgi_app, mapper, use_method_override=True,
+ path_info=True):
+ """Create a Route middleware object
+
+ Using the use_method_override keyword will require Paste to be
+ installed, and your application should use Paste's WSGIRequest object
+ as it will properly handle POST issues with wsgi.input should Routes
+ check it.
+
+ If path_info is True, then should a route var contain path_info, the
+ SCRIPT_NAME and PATH_INFO will be altered accordingly. This should be
+ used with routes like:
+
+ .. code-block:: Python
+
+ map.connect('blog/*path_info', controller='blog', path_info='')
+ """
+ self.app = wsgi_app
+ self.mapper = mapper
+ self.use_method_override = use_method_override
+ self.path_info = path_info
+
+ def __call__(self, environ, start_response):
+ config = request_config()
+ config.mapper = self.mapper
+
+ old_method = None
+ if self.use_method_override:
+ req = WSGIRequest(environ)
+ if '_method' in environ.get('QUERY_STRING', '') and '_method' in req.GET:
+ old_method = environ['REQUEST_METHOD']
+ environ['REQUEST_METHOD'] = req.GET['_method']
+ elif environ['REQUEST_METHOD'] == 'POST' and '_method' in req.POST:
+ old_method = environ['REQUEST_METHOD']
+ environ['REQUEST_METHOD'] = req.POST['_method']
+
+ config.environ = environ
+ match = config.mapper_dict
+
+ if old_method:
+ environ['REQUEST_METHOD'] = old_method
+
+ if not match:
+ return self.not_found(environ, start_response)
+
+ for k,v in match.iteritems():
+ if v:
+ match[k] = urllib.unquote_plus(v)
+
+ environ['wsgiorg.routing_args'] = ((), match)
+
+ # If the route included a path_info attribute and it should be used to
+ # alter the environ, we'll pull it out
+ if self.path_info and match.get('path_info'):
+ oldpath = environ['PATH_INFO']
+ newpath = match.get('path_info') or ''
+ environ['PATH_INFO'] = newpath
+ if not environ['PATH_INFO'].startswith('/'):
+ environ['PATH_INFO'] = '/' + environ['PATH_INFO']
+ environ['SCRIPT_NAME'] += re.sub(r'^(.*?)/' + newpath + '$', r'\1', oldpath)
+ if environ['SCRIPT_NAME'].endswith('/'):
+ environ['SCRIPT_NAME'] = environ['SCRIPT_NAME'][:-1]
+
+ return self.app(environ, start_response)
+
+ def not_found(self, environ, start_response):
+ start_response('404 Not Found', [('Content-type', 'text/plain')])
+ return ['Not found']
diff --git a/setup.py b/setup.py
index 527cb66..f5b1299 100644
--- a/setup.py
+++ b/setup.py
@@ -3,7 +3,7 @@ use_setuptools()
from setuptools import setup, find_packages
setup(name="Routes",
- version='1.5.3',
+ version='1.6',
description='Routing Recognition and Generation Tools',
long_description="""
A Routing package for Python that matches URL's to dicts and vice versa