diff options
Diffstat (limited to 'netlib')
-rw-r--r-- | netlib/debug.py | 4 | ||||
-rw-r--r-- | netlib/encoding.py | 25 | ||||
-rw-r--r-- | netlib/http/headers.py | 1 | ||||
-rw-r--r-- | netlib/http/http2/__init__.py | 6 | ||||
-rw-r--r-- | netlib/http/http2/framereader.py | 9 | ||||
-rw-r--r-- | netlib/http/response.py | 19 | ||||
-rw-r--r-- | netlib/strutils.py | 5 |
7 files changed, 49 insertions, 20 deletions
diff --git a/netlib/debug.py b/netlib/debug.py index 29c7f655..f9c700de 100644 --- a/netlib/debug.py +++ b/netlib/debug.py @@ -37,7 +37,7 @@ def sysinfo(): return "\n".join(data) -def dump_info(sig, frm, file=sys.stdout): # pragma: no cover +def dump_info(signal=None, frame=None, file=sys.stdout): # pragma: no cover print("****************************************************", file=file) print("Summary", file=file) print("=======", file=file) @@ -81,7 +81,7 @@ def dump_info(sig, frm, file=sys.stdout): # pragma: no cover print("****************************************************", file=file) -def dump_stacks(signal, frame, file=sys.stdout): +def dump_stacks(signal=None, frame=None, file=sys.stdout): id2name = dict([(th.ident, th.name) for th in threading.enumerate()]) code = [] for threadId, stack in sys._current_frames().items(): diff --git a/netlib/encoding.py b/netlib/encoding.py index 9c8acff7..9b8b3868 100644 --- a/netlib/encoding.py +++ b/netlib/encoding.py @@ -5,7 +5,9 @@ from __future__ import absolute_import import codecs import collections +import six from io import BytesIO + import gzip import zlib import brotli @@ -32,6 +34,9 @@ def decode(encoded, encoding, errors='strict'): Raises: ValueError, if decoding fails. """ + if len(encoded) == 0: + return encoded + global _cache cached = ( isinstance(encoded, bytes) and @@ -49,11 +54,14 @@ def decode(encoded, encoding, errors='strict'): if encoding in ("gzip", "deflate", "br"): _cache = CachedDecode(encoded, encoding, errors, decoded) return decoded + except TypeError: + raise except Exception as e: - raise ValueError("{} when decoding {} with {}".format( + raise ValueError("{} when decoding {} with {}: {}".format( type(e).__name__, repr(encoded)[:10], repr(encoding), + repr(e), )) @@ -68,6 +76,9 @@ def encode(decoded, encoding, errors='strict'): Raises: ValueError, if encoding fails. """ + if len(decoded) == 0: + return decoded + global _cache cached = ( isinstance(decoded, bytes) and @@ -79,17 +90,23 @@ def encode(decoded, encoding, errors='strict'): return _cache.encoded try: try: - encoded = custom_encode[encoding](decoded) + value = decoded + if not six.PY2 and isinstance(value, six.string_types): + value = decoded.encode() + encoded = custom_encode[encoding](value) except KeyError: encoded = codecs.encode(decoded, encoding, errors) if encoding in ("gzip", "deflate", "br"): _cache = CachedDecode(encoded, encoding, errors, decoded) return encoded + except TypeError: + raise except Exception as e: - raise ValueError("{} when encoding {} with {}".format( + raise ValueError("{} when encoding {} with {}: {}".format( type(e).__name__, repr(decoded)[:10], repr(encoding), + repr(e), )) @@ -145,12 +162,14 @@ def encode_deflate(content): custom_decode = { + "none": identity, "identity": identity, "gzip": decode_gzip, "deflate": decode_deflate, "br": decode_brotli, } custom_encode = { + "none": identity, "identity": identity, "gzip": encode_gzip, "deflate": encode_deflate, diff --git a/netlib/http/headers.py b/netlib/http/headers.py index 131e8ce5..b55874ca 100644 --- a/netlib/http/headers.py +++ b/netlib/http/headers.py @@ -14,6 +14,7 @@ if six.PY2: # pragma: no cover return x def _always_bytes(x): + strutils.always_bytes(x, "utf-8", "replace") # raises a TypeError if x != str/bytes/None. return x else: # While headers _should_ be ASCII, it's not uncommon for certain headers to be utf-8 encoded. diff --git a/netlib/http/http2/__init__.py b/netlib/http/http2/__init__.py index 60064190..7f84a1ab 100644 --- a/netlib/http/http2/__init__.py +++ b/netlib/http/http2/__init__.py @@ -1,8 +1,10 @@ from __future__ import absolute_import, print_function, division -from netlib.http.http2 import framereader + +from netlib.http.http2.framereader import read_raw_frame, parse_frame from netlib.http.http2.utils import parse_headers __all__ = [ - "framereader", + "read_raw_frame", + "parse_frame", "parse_headers", ] diff --git a/netlib/http/http2/framereader.py b/netlib/http/http2/framereader.py index eb9b069a..8b7cfffb 100644 --- a/netlib/http/http2/framereader.py +++ b/netlib/http/http2/framereader.py @@ -4,7 +4,7 @@ import hyperframe from ...exceptions import HttpException -def http2_read_raw_frame(rfile): +def read_raw_frame(rfile): header = rfile.safe_read(9) length = int(codecs.encode(header[:3], 'hex_codec'), 16) @@ -15,8 +15,11 @@ def http2_read_raw_frame(rfile): return [header, body] -def http2_read_frame(rfile): - header, body = http2_read_raw_frame(rfile) +def parse_frame(header, body=None): + if body is None: + body = header[9:] + header = header[:9] + frame, length = hyperframe.frame.Frame.parse_frame_header(header) frame.parse_body(memoryview(body)) return frame diff --git a/netlib/http/response.py b/netlib/http/response.py index ae29298f..385e233a 100644 --- a/netlib/http/response.py +++ b/netlib/http/response.py @@ -84,15 +84,6 @@ class Response(message.Message): (), None ) - # Assign this manually to update the content-length header. - if isinstance(content, bytes): - resp.content = content - elif isinstance(content, str): - resp.text = content - else: - raise TypeError("Expected content to be str or bytes, but is {}.".format( - type(content).__name__ - )) # Headers can be list or dict, we differentiate here. if isinstance(headers, dict): @@ -104,6 +95,16 @@ class Response(message.Message): type(headers).__name__ )) + # Assign this manually to update the content-length header. + if isinstance(content, bytes): + resp.content = content + elif isinstance(content, str): + resp.text = content + else: + raise TypeError("Expected content to be str or bytes, but is {}.".format( + type(content).__name__ + )) + return resp @property diff --git a/netlib/strutils.py b/netlib/strutils.py index 4cb3b805..d43c2aab 100644 --- a/netlib/strutils.py +++ b/netlib/strutils.py @@ -8,7 +8,10 @@ import six def always_bytes(unicode_or_bytes, *encode_args): if isinstance(unicode_or_bytes, six.text_type): return unicode_or_bytes.encode(*encode_args) - return unicode_or_bytes + elif isinstance(unicode_or_bytes, bytes) or unicode_or_bytes is None: + return unicode_or_bytes + else: + raise TypeError("Expected str or bytes, but got {}.".format(type(unicode_or_bytes).__name__)) def native(s, *encoding_opts): |