From a27f6f88efdc1f830e94b422d58d3b29b66c8908 Mon Sep 17 00:00:00 2001 From: ilvalle Date: Sat, 11 Jun 2016 15:45:27 +0200 Subject: [PATCH] fix serializers, websocket_messaging --- gluon/contrib/websocket_messaging.py | 34 ++++++++++++++++++++++------ gluon/custom_import.py | 4 ++-- gluon/serializers.py | 8 +++---- gluon/sqlhtml.py | 2 +- gluon/tests/__init__.py | 2 +- 5 files changed, 35 insertions(+), 15 deletions(-) diff --git a/gluon/contrib/websocket_messaging.py b/gluon/contrib/websocket_messaging.py index 5531629a..84fe55cc 100644 --- a/gluon/contrib/websocket_messaging.py +++ b/gluon/contrib/websocket_messaging.py @@ -84,7 +84,6 @@ Tornado code inspired by http://thomas.pelletier.im/2010/08/websocket-tornado-re """ from __future__ import print_function - import tornado.httpserver import tornado.websocket import tornado.ioloop @@ -92,17 +91,38 @@ import tornado.web import hmac import sys import optparse -import urllib import time +import sys +if (sys.version_info[0] == 2): + from urllib import urlencode, urlopen + def to_bytes(obj, charset='utf-8', errors='strict'): + if obj is None: + return None + if isinstance(obj, (bytes, bytearray, buffer)): + return bytes(obj) + if isinstance(obj, unicode): + return obj.encode(charset, errors) + raise TypeError('Expected bytes') +else: + from urllib.request import urlopen + from urllib.parse import urlencode + def to_bytes(obj, charset='utf-8', errors='strict'): + if obj is None: + return None + if isinstance(obj, (bytes, bytearray, memoryview)): + return bytes(obj) + if isinstance(obj, str): + return obj.encode(charset, errors) + raise TypeError('Expected bytes') listeners, names, tokens = {}, {}, {} def websocket_send(url, message, hmac_key=None, group='default'): - sig = hmac_key and hmac.new(hmac_key, message).hexdigest() or '' - params = urllib.urlencode( + sig = hmac_key and hmac.new(to_bytes(hmac_key), to_bytes(message)).hexdigest() or '' + params = urlencode( {'message': message, 'signature': sig, 'group': group}) - f = urllib.urlopen(url, params) + f = urlopen(url, to_bytes(params)) data = f.read() f.close() return data @@ -121,7 +141,7 @@ class PostHandler(tornado.web.RequestHandler): print('%s:MESSAGE to %s:%s' % (time.time(), group, message)) if hmac_key: signature = self.request.arguments['signature'][0] - if not hmac.new(hmac_key, message).hexdigest() == signature: + if not to_bytes(hmac.new(to_bytes(hmac_key), to_bytes(message)).hexdigest()) == signature: self.send_error(401) for client in listeners.get(group, []): client.write_message(message) @@ -140,7 +160,7 @@ class TokenHandler(tornado.web.RequestHandler): message = self.request.arguments['message'][0] if hmac_key: signature = self.request.arguments['signature'][0] - if not hmac.new(hmac_key, message).hexdigest() == signature: + if not to_bytes(hmac.new(to_bytes(hmac_key), to_bytes(message)).hexdigest()) == signature: self.send_error(401) tokens[message] = None diff --git a/gluon/custom_import.py b/gluon/custom_import.py index 9dfb937c..4bd3ab5f 100644 --- a/gluon/custom_import.py +++ b/gluon/custom_import.py @@ -8,7 +8,7 @@ Support for smart import syntax for web2py applications ------------------------------------------------------- """ -from gluon._compat import builtin +from gluon._compat import builtin, unicodeT, PY2 import os import sys import threading @@ -47,7 +47,7 @@ def custom_importer(name, globals=None, locals=None, fromlist=None, level=-1): If the import fails, it falls back on naive_importer """ - if isinstance(name, unicode): + if isinstance(name, unicodeT) and PY2: name = name.encode('utf8') globals = globals or {} diff --git a/gluon/serializers.py b/gluon/serializers.py index 61fe88bb..559eb725 100644 --- a/gluon/serializers.py +++ b/gluon/serializers.py @@ -10,7 +10,7 @@ from gluon.html import TAG, XmlComponent, xmlescape from gluon.languages import lazyT import gluon.contrib.rss2 as rss2 import json as json_parser -from gluon._compat import long +from gluon._compat import long, to_native, unicodeT have_yaml = True try: @@ -43,7 +43,7 @@ def cast_keys(o, cast=str, encoding="utf-8"): else: newobj = Storage() for k, v in o.items(): - if (cast == str) and isinstance(k, unicode): + if (cast == str) and isinstance(k, unicodeT): key = k.encode(encoding) else: key = cast(k) @@ -88,7 +88,7 @@ def custom_json(o): elif isinstance(o, lazyT): return str(o) elif isinstance(o, XmlComponent): - return str(o) + return to_native(o.xml()) elif isinstance(o, set): return list(o) elif hasattr(o, 'as_list') and callable(o.as_list): @@ -161,7 +161,7 @@ def ics(events, title=None, link=None, timeshift=0, calname=True, return s def safe_encode(text): - if not isinstance(text, (str, unicode)): + if not isinstance(text, (str, unicodeT)): text = str(text) try: text = text.encode('utf8','replace') diff --git a/gluon/sqlhtml.py b/gluon/sqlhtml.py index 84e25d3e..6bf336b4 100644 --- a/gluon/sqlhtml.py +++ b/gluon/sqlhtml.py @@ -3487,7 +3487,7 @@ class ExporterTSV(ExportClass): import codecs final.write(codecs.BOM_UTF16) writer.writerow( - [unicode(col).encode("utf8") for col in self.rows.colnames]) + [to_unicode(col, "utf8") for col in self.rows.colnames]) data = out.getvalue().decode("utf8") data = data.encode("utf-16") data = data[2:] diff --git a/gluon/tests/__init__.py b/gluon/tests/__init__.py index 46a0f107..cb3f7c13 100644 --- a/gluon/tests/__init__.py +++ b/gluon/tests/__init__.py @@ -16,12 +16,12 @@ from .test_router import * from .test_validators import * from .test_tools import * from .test_utils import * +from .test_serializers import * if sys.version[:3] == '2.7': from .test_compileapp import * from .test_is_url import * from .test_languages import * - from .test_serializers import * from .test_appadmin import * from .test_scheduler import * from .test_web import *