Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksey Lim <alsroot@sugarlabs.org>2014-01-25 08:39:16 (GMT)
committer Aleksey Lim <alsroot@sugarlabs.org>2014-01-25 08:39:16 (GMT)
commita94f10a83f2a1aa441af793e8ccf3e04a4693e0e (patch)
tree6152fa51e0268c6540ec125f458860911bd512ae
parentdf9f0880088d85a57036cbf0b3091993056fa8e2 (diff)
Do not fail on unicode in HTTP headers
-rw-r--r--sugar_network/toolkit/router.py18
-rwxr-xr-xtests/units/toolkit/router.py26
2 files changed, 35 insertions, 9 deletions
diff --git a/sugar_network/toolkit/router.py b/sugar_network/toolkit/router.py
index 7f2c268..9a430b7 100644
--- a/sugar_network/toolkit/router.py
+++ b/sugar_network/toolkit/router.py
@@ -396,14 +396,14 @@ class Response(dict):
for key, value in dict.items(self):
if type(value) in (list, tuple):
for i in value:
- result.append((key, str(i)))
+ result.append((_to_ascii(key), _to_ascii(i)))
else:
- result.append((key, str(value)))
+ result.append((_to_ascii(key), _to_ascii(value)))
return result
def __repr__(self):
items = ['%s=%r' % i for i in self.items() + self.meta.items()]
- return '<Response %s>' % ' '.join(items)
+ return '<Response %r>' % items
def __contains__(self, key):
dict.__contains__(self, key.lower())
@@ -576,7 +576,7 @@ class Router(object):
response.content_length = len(result) if result else 0
for key, value in response.meta.items():
- response.set('X-SN-%s' % str(key), json.dumps(value))
+ response.set('X-SN-%s' % _to_ascii(key), json.dumps(value))
if request.method == 'HEAD' and result is not None:
_logger.warning('Content from HEAD response is ignored')
@@ -750,7 +750,7 @@ def _filename(names, mime_type):
for name in names:
if isinstance(name, dict):
name = toolkit.gettext(name)
- parts.append(''.join([i.capitalize() for i in str(name).split()]))
+ parts.append(''.join([i.capitalize() for i in name.split()]))
result = '-'.join(parts)
if mime_type:
if not mimetypes.inited:
@@ -832,6 +832,14 @@ def _parse_accept_language(value):
return langs
+def _to_ascii(value):
+ if not isinstance(value, basestring):
+ return str(value)
+ if isinstance(value, unicode):
+ return value.encode('utf8')
+ return value
+
+
class _Routes(dict):
def __init__(self, parent=None):
diff --git a/tests/units/toolkit/router.py b/tests/units/toolkit/router.py
index e229f2d..a9b17f2 100755
--- a/tests/units/toolkit/router.py
+++ b/tests/units/toolkit/router.py
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+# -*- coding: utf-8 -*-
# sugar-lint: disable
import os
@@ -8,7 +9,7 @@ from cStringIO import StringIO
from __init__ import tests, src_root
-from sugar_network import db
+from sugar_network import db, client
from sugar_network.toolkit.router import Blob, Router, Request, _parse_accept_language, route, fallbackroute, preroute, postroute, _filename
from sugar_network.toolkit import default_lang, http, coroutine
@@ -1175,8 +1176,6 @@ class RouterTest(tests.Test):
self.assertEqual('Foo-Bar', _filename(['foo', 'bar'], None))
self.assertEqual('FOO-BaR', _filename([' f o o', ' ba r '], None))
- self.assertEqual('Foo-3', _filename(['foo', 3], None))
-
self.assertEqual('12-3', _filename(['/1/2/', '/3/'], None))
self.assertEqual('Foo.png', _filename('foo', 'image/png'))
@@ -1185,7 +1184,7 @@ class RouterTest(tests.Test):
self.assertEqual('Eng', _filename({default_lang(): 'eng'}, None))
self.assertEqual('Eng', _filename([{default_lang(): 'eng'}], None))
- self.assertEqual('Bar-1', _filename([{'lang': 'foo', default_lang(): 'bar'}, 1], None))
+ self.assertEqual('Bar-1', _filename([{'lang': 'foo', default_lang(): 'bar'}, '1'], None))
def test_BlobsDisposition(self):
self.touch(('blob.data', 'value'))
@@ -1384,6 +1383,25 @@ class RouterTest(tests.Test):
events)
del events[:]
+ def test_UnicodeInHeaders(self):
+
+ class Routes(object):
+
+ @route('HEAD')
+ def probe(self, request, response):
+ response['фоо'] = 'бар'
+ response[u'йцу'] = u'кен'
+
+ server = coroutine.WSGIServer(('127.0.0.1', client.ipc_port.value), Router(Routes()))
+ coroutine.spawn(server.serve_forever)
+ coroutine.dispatch()
+
+ conn = http.Connection('http://127.0.0.1:%s' % client.ipc_port.value)
+ headers = conn.request('HEAD', []).headers
+
+ self.assertEqual('бар', headers.get('фоо'))
+ self.assertEqual('кен', headers.get('йцу'))
+
if __name__ == '__main__':
tests.main()