Merge branch 'achille-roussel-wsaccel'
This commit is contained in:
@@ -26,6 +26,24 @@ import os
|
|||||||
from ._exceptions import *
|
from ._exceptions import *
|
||||||
from ._utils import validate_utf8
|
from ._utils import validate_utf8
|
||||||
|
|
||||||
|
try:
|
||||||
|
# If wsaccel is available we use compiled routines to mask data.
|
||||||
|
from wsaccel.xormask import XorMaskerSimple
|
||||||
|
|
||||||
|
def _mask(_m, _d):
|
||||||
|
return XorMaskerSimple(_m).process(_d)
|
||||||
|
|
||||||
|
except ImportError:
|
||||||
|
# wsaccel is not available, we rely on python implementations.
|
||||||
|
def _mask(_m, _d):
|
||||||
|
for i in range(len(_d)):
|
||||||
|
_d[i] ^= _m[i % 4]
|
||||||
|
|
||||||
|
if six.PY3:
|
||||||
|
return _d.tobytes()
|
||||||
|
else:
|
||||||
|
return _d.tostring()
|
||||||
|
|
||||||
# closing frame status codes.
|
# closing frame status codes.
|
||||||
STATUS_NORMAL = 1000
|
STATUS_NORMAL = 1000
|
||||||
STATUS_GOING_AWAY = 1001
|
STATUS_GOING_AWAY = 1001
|
||||||
@@ -208,6 +226,7 @@ class ABNF(object):
|
|||||||
"""
|
"""
|
||||||
if data == None:
|
if data == None:
|
||||||
data = ""
|
data = ""
|
||||||
|
|
||||||
if isinstance(mask_key, six.text_type):
|
if isinstance(mask_key, six.text_type):
|
||||||
mask_key = six.b(mask_key)
|
mask_key = six.b(mask_key)
|
||||||
|
|
||||||
@@ -216,14 +235,7 @@ class ABNF(object):
|
|||||||
|
|
||||||
_m = array.array("B", mask_key)
|
_m = array.array("B", mask_key)
|
||||||
_d = array.array("B", data)
|
_d = array.array("B", data)
|
||||||
for i in range(len(_d)):
|
return _mask(_m, _d)
|
||||||
_d[i] ^= _m[i % 4]
|
|
||||||
|
|
||||||
if six.PY3:
|
|
||||||
return _d.tobytes()
|
|
||||||
else:
|
|
||||||
return _d.tostring()
|
|
||||||
|
|
||||||
|
|
||||||
class frame_buffer(object):
|
class frame_buffer(object):
|
||||||
_HEADER_MASK_INDEX = 5
|
_HEADER_MASK_INDEX = 5
|
||||||
|
@@ -119,7 +119,7 @@ def _open_socket(addrinfo_list, sockopt, timeout):
|
|||||||
|
|
||||||
|
|
||||||
def _can_use_sni():
|
def _can_use_sni():
|
||||||
return six.Py2 and sys.version_info >= (2, 7, 9) or sys.version_info >= (3, 2)
|
return six.PY2 and sys.version_info >= (2, 7, 9) or sys.version_info >= (3, 2)
|
||||||
|
|
||||||
|
|
||||||
def _wrap_sni_socket(sock, sslopt, hostname, check_hostname):
|
def _wrap_sni_socket(sock, sslopt, hostname, check_hostname):
|
||||||
|
@@ -28,43 +28,63 @@ class NoLock(object):
|
|||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def __exit__(self,type, value, traceback):
|
def __exit__(self, type, value, traceback):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
# If wsaccel is availabe we use compiled routines to validate UTF-8
|
||||||
|
# strings.
|
||||||
|
from wsaccel.utf8validator import Utf8Validator
|
||||||
|
|
||||||
# UTF-8 validator
|
def _validate_utf8(utfbytes):
|
||||||
# python implementation of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
|
return Utf8Validator().validate(utfbytes)[0]
|
||||||
|
|
||||||
UTF8_ACCEPT = 0
|
except ImportError:
|
||||||
UTF8_REJECT=12
|
# UTF-8 validator
|
||||||
|
# python implementation of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
|
||||||
|
|
||||||
_UTF8D = [
|
_UTF8_ACCEPT = 0
|
||||||
# The first part of the table maps bytes to character classes that
|
_UTF8_REJECT = 12
|
||||||
# to reduce the size of the transition table and create bitmasks.
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
||||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
|
|
||||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
|
||||||
8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
|
||||||
10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
|
|
||||||
|
|
||||||
# The second part is a transition table that maps a combination
|
_UTF8D = [
|
||||||
# of a state of the automaton and a character class to a state.
|
# The first part of the table maps bytes to character classes that
|
||||||
0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12,
|
# to reduce the size of the transition table and create bitmasks.
|
||||||
12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12,
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12,
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12,
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
12,36,12,12,12,12,12,12,12,12,12,12, ]
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
|
||||||
|
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
||||||
|
8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||||
|
10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
|
||||||
|
|
||||||
def _decode(state, codep, ch):
|
# The second part is a transition table that maps a combination
|
||||||
tp = _UTF8D[ch]
|
# of a state of the automaton and a character class to a state.
|
||||||
|
0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12,
|
||||||
|
12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12,
|
||||||
|
12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12,
|
||||||
|
12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12,
|
||||||
|
12,36,12,12,12,12,12,12,12,12,12,12, ]
|
||||||
|
|
||||||
codep = (ch & 0x3f ) | (codep << 6) if (state != UTF8_ACCEPT) else (0xff >> tp) & (ch)
|
def _decode(state, codep, ch):
|
||||||
state = _UTF8D[256 + state + tp]
|
tp = _UTF8D[ch]
|
||||||
|
|
||||||
return state, codep;
|
codep = (ch & 0x3f ) | (codep << 6) if (state != _UTF8_ACCEPT) else (0xff >> tp) & (ch)
|
||||||
|
state = _UTF8D[256 + state + tp]
|
||||||
|
|
||||||
|
return state, codep;
|
||||||
|
|
||||||
|
def _validate_utf8(utfbytes):
|
||||||
|
state = _UTF8_ACCEPT
|
||||||
|
codep = 0
|
||||||
|
for i in utfbytes:
|
||||||
|
if six.PY2:
|
||||||
|
i = ord(i)
|
||||||
|
state, codep = _decode(state, codep, i)
|
||||||
|
if state == _UTF8_REJECT:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
def validate_utf8(utfbytes):
|
def validate_utf8(utfbytes):
|
||||||
"""
|
"""
|
||||||
@@ -72,17 +92,7 @@ def validate_utf8(utfbytes):
|
|||||||
utfbytes: utf byte string to check.
|
utfbytes: utf byte string to check.
|
||||||
return value: if valid utf8 string, return true. Otherwise, return false.
|
return value: if valid utf8 string, return true. Otherwise, return false.
|
||||||
"""
|
"""
|
||||||
state = UTF8_ACCEPT
|
return _validate_utf8(utfbytes)
|
||||||
codep = 0
|
|
||||||
for i in utfbytes:
|
|
||||||
if six.PY2:
|
|
||||||
i = ord(i)
|
|
||||||
state, codep = _decode(state, codep, i)
|
|
||||||
if state == UTF8_REJECT:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def extract_err_message(exception):
|
def extract_err_message(exception):
|
||||||
if exception.args:
|
if exception.args:
|
||||||
|
Reference in New Issue
Block a user