From 35f4c29a3f0c6f946796cf3ac3fd056de69a72df Mon Sep 17 00:00:00 2001 From: Fred Drake Date: Fri, 21 Nov 2014 16:10:54 -0500 Subject: [PATCH 1/3] encode unicode redirect URLs automatically --- bobo/README.txt | 2 ++ bobo/src/bobo.py | 12 ++++++++- .../src/bobodoctestumentation/more.txt | 25 +++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/bobo/README.txt b/bobo/README.txt index bdddc64..acb12e4 100644 --- a/bobo/README.txt +++ b/bobo/README.txt @@ -22,6 +22,8 @@ To learn more. visit: http://bobo.digicool.com Change History ============== +- Bobo will encode Unicode URLs for redirects automatically. + - Bobo will pass resource function arguments from data in JSON request bodies. 2.1.1 2014-07-06 diff --git a/bobo/src/bobo.py b/bobo/src/bobo.py index 3023b3f..c30f22c 100644 --- a/bobo/src/bobo.py +++ b/bobo/src/bobo.py @@ -249,8 +249,15 @@ def __call__(self, environ, start_response): # Maybe middleware can be more tricky? request.charset = 'utf8' + def start_bobo_response(status, headers): + headers = list(headers or ()) + for i, (k, v) in enumerate(headers): + if k.lower() == "location" and isinstance(v, unicode): + headers[i] = k, v.encode("utf-8") + start_response(status, headers) + return self.bobo_response(request, request.path_info, request.method - )(environ, start_response) + )(environ, start_bobo_response) def build_response(self, request, method, data): """Build a response object from raw data. @@ -334,6 +341,9 @@ def _err_response(status, method, title, message, headers=()): """ +def _massage_headers(headers): + return headers + def redirect(url, status=302, body=None, content_type="text/html; charset=UTF-8"): """Generate a response to redirect to a URL. diff --git a/bobodoctestumentation/src/bobodoctestumentation/more.txt b/bobodoctestumentation/src/bobodoctestumentation/more.txt index 8c8fb52..deb79bb 100644 --- a/bobodoctestumentation/src/bobodoctestumentation/more.txt +++ b/bobodoctestumentation/src/bobodoctestumentation/more.txt @@ -1087,3 +1087,28 @@ with an Allow header. >>> app.request('/users/54321', ... method="OPTIONS", status=405).headers["Allow"] 'GET, HEAD, POST, PUT' + + +Automatic encoding of redirect destinations +------------------------------------------- + +Since URLs are often computed based on request data, it's easy for +applications to generate Unicode URLs. If we get this, UTF-8 is +generated automatically:: + + import bobo + + @bobo.get("/redirect-me") + def redirect(): + return bobo.redirect(u"http://www.\u0113xample.com/") + + +.. -> src + + >>> update_module('redirection', src) + >>> app = webtest.TestApp(bobo.Application( + ... bobo_resources='redirection')) + + >>> response = app.get("/redirect-me", status=302) + >>> response.headers["location"] + 'http://www.\xc4\x93xample.com/' From ab62e19e90ebc7223a9075d2135b14a3508ed9da Mon Sep 17 00:00:00 2001 From: Fred Drake Date: Fri, 21 Nov 2014 16:26:13 -0500 Subject: [PATCH 2/3] simplify; only encode for bobo.redirect; separate documentation from test --- bobo/src/bobo.py | 11 +++------- .../src/bobodoctestumentation/main.test | 8 +++++++ .../src/bobodoctestumentation/more.txt | 21 ++----------------- 3 files changed, 13 insertions(+), 27 deletions(-) diff --git a/bobo/src/bobo.py b/bobo/src/bobo.py index c30f22c..ca7b4f3 100644 --- a/bobo/src/bobo.py +++ b/bobo/src/bobo.py @@ -249,15 +249,8 @@ def __call__(self, environ, start_response): # Maybe middleware can be more tricky? request.charset = 'utf8' - def start_bobo_response(status, headers): - headers = list(headers or ()) - for i, (k, v) in enumerate(headers): - if k.lower() == "location" and isinstance(v, unicode): - headers[i] = k, v.encode("utf-8") - start_response(status, headers) - return self.bobo_response(request, request.path_info, request.method - )(environ, start_bobo_response) + )(environ, start_response) def build_response(self, request, method, data): """Build a response object from raw data. @@ -355,6 +348,8 @@ def redirect(url, status=302, body=None, """ if body is None: body = u'See %s' % url + if isinstance(url, unicode): + url = url.encode('utf-8') response = webob.Response(status=status, headerlist=[('Location', url)]) response.content_type = content_type response.unicode_body = body diff --git a/bobodoctestumentation/src/bobodoctestumentation/main.test b/bobodoctestumentation/src/bobodoctestumentation/main.test index cba04f6..c9773bf 100644 --- a/bobodoctestumentation/src/bobodoctestumentation/main.test +++ b/bobodoctestumentation/src/bobodoctestumentation/main.test @@ -336,3 +336,11 @@ Ordering >>> app = makeapp(bobo_resources='bobo.testmodule1') >>> app.get('/o').text 'f3' + + +Automatic encoding of redirect destinations +------------------------------------------- + + >>> response = bobo.redirect(u"http://www.\u0113xample.com/") + >>> response.headers["location"] + 'http://www.\xc4\x93xample.com/' diff --git a/bobodoctestumentation/src/bobodoctestumentation/more.txt b/bobodoctestumentation/src/bobodoctestumentation/more.txt index deb79bb..34408cd 100644 --- a/bobodoctestumentation/src/bobodoctestumentation/more.txt +++ b/bobodoctestumentation/src/bobodoctestumentation/more.txt @@ -1093,22 +1093,5 @@ Automatic encoding of redirect destinations ------------------------------------------- Since URLs are often computed based on request data, it's easy for -applications to generate Unicode URLs. If we get this, UTF-8 is -generated automatically:: - - import bobo - - @bobo.get("/redirect-me") - def redirect(): - return bobo.redirect(u"http://www.\u0113xample.com/") - - -.. -> src - - >>> update_module('redirection', src) - >>> app = webtest.TestApp(bobo.Application( - ... bobo_resources='redirection')) - - >>> response = app.get("/redirect-me", status=302) - >>> response.headers["location"] - 'http://www.\xc4\x93xample.com/' +applications to generate Unicode URLs. For this reason, unicode URL's +passed to ``bobo.redirect`` are UTF-8 encoded. From 57fc685ebd536e8111ecff8aeda4383f79b427f4 Mon Sep 17 00:00:00 2001 From: Fred Drake Date: Fri, 21 Nov 2014 16:30:43 -0500 Subject: [PATCH 3/3] remove turd --- bobo/src/bobo.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/bobo/src/bobo.py b/bobo/src/bobo.py index ca7b4f3..78e38c9 100644 --- a/bobo/src/bobo.py +++ b/bobo/src/bobo.py @@ -334,9 +334,6 @@ def _err_response(status, method, title, message, headers=()): """ -def _massage_headers(headers): - return headers - def redirect(url, status=302, body=None, content_type="text/html; charset=UTF-8"): """Generate a response to redirect to a URL.