aboutsummaryrefslogtreecommitdiffstats
path: root/netlib
diff options
context:
space:
mode:
Diffstat (limited to 'netlib')
-rw-r--r--netlib/debug.py4
-rw-r--r--netlib/encoding.py25
-rw-r--r--netlib/http/headers.py1
-rw-r--r--netlib/http/http2/__init__.py6
-rw-r--r--netlib/http/http2/framereader.py9
-rw-r--r--netlib/http/response.py19
-rw-r--r--netlib/strutils.py5
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):