aboutsummaryrefslogtreecommitdiffstats
path: root/netlib
diff options
context:
space:
mode:
Diffstat (limited to 'netlib')
-rw-r--r--netlib/http/request.py16
-rw-r--r--netlib/http/response.py66
-rw-r--r--netlib/strutils.py3
3 files changed, 76 insertions, 9 deletions
diff --git a/netlib/http/request.py b/netlib/http/request.py
index d59fead4..666a5869 100644
--- a/netlib/http/request.py
+++ b/netlib/http/request.py
@@ -20,8 +20,20 @@ host_header_re = re.compile(r"^(?P<host>[^:]+|\[.+\])(?::(?P<port>\d+))?$")
class RequestData(message.MessageData):
- def __init__(self, first_line_format, method, scheme, host, port, path, http_version, headers=(), content=None,
- timestamp_start=None, timestamp_end=None):
+ def __init__(
+ self,
+ first_line_format,
+ method,
+ scheme,
+ host,
+ port,
+ path,
+ http_version,
+ headers=(),
+ content=None,
+ timestamp_start=None,
+ timestamp_end=None
+ ):
if isinstance(method, six.text_type):
method = method.encode("ascii", "strict")
if isinstance(scheme, six.text_type):
diff --git a/netlib/http/response.py b/netlib/http/response.py
index 85f54940..ae29298f 100644
--- a/netlib/http/response.py
+++ b/netlib/http/response.py
@@ -1,19 +1,32 @@
from __future__ import absolute_import, print_function, division
-from email.utils import parsedate_tz, formatdate, mktime_tz
-import time
import six
-
+import time
+from email.utils import parsedate_tz, formatdate, mktime_tz
+from netlib import human
+from netlib import multidict
from netlib.http import cookies
from netlib.http import headers as nheaders
from netlib.http import message
-from netlib import multidict
-from netlib import human
+from netlib.http import status_codes
+from typing import AnyStr # noqa
+from typing import Dict # noqa
+from typing import Iterable # noqa
+from typing import Tuple # noqa
+from typing import Union # noqa
class ResponseData(message.MessageData):
- def __init__(self, http_version, status_code, reason=None, headers=(), content=None,
- timestamp_start=None, timestamp_end=None):
+ def __init__(
+ self,
+ http_version,
+ status_code,
+ reason=None,
+ headers=(),
+ content=None,
+ timestamp_start=None,
+ timestamp_end=None
+ ):
if isinstance(http_version, six.text_type):
http_version = http_version.encode("ascii", "strict")
if isinstance(reason, six.text_type):
@@ -54,6 +67,45 @@ class Response(message.Message):
details=details
)
+ @classmethod
+ def make(
+ cls,
+ status_code=200, # type: int
+ content=b"", # type: AnyStr
+ headers=() # type: Union[Dict[AnyStr, AnyStr], Iterable[Tuple[bytes, bytes]]]
+ ):
+ """
+ Simplified API for creating response objects.
+ """
+ resp = cls(
+ b"HTTP/1.1",
+ status_code,
+ status_codes.RESPONSES.get(status_code, "").encode(),
+ (),
+ 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):
+ resp.headers = nheaders.Headers(**headers)
+ elif isinstance(headers, Iterable):
+ resp.headers = nheaders.Headers(headers)
+ else:
+ raise TypeError("Expected headers to be an iterable or dict, but is {}.".format(
+ type(headers).__name__
+ ))
+
+ return resp
+
@property
def status_code(self):
"""
diff --git a/netlib/strutils.py b/netlib/strutils.py
index 4a46b6b1..4cb3b805 100644
--- a/netlib/strutils.py
+++ b/netlib/strutils.py
@@ -121,6 +121,9 @@ def escaped_str_to_bytes(data):
def is_mostly_bin(s):
# type: (bytes) -> bool
+ if not s or len(s) == 0:
+ return False
+
return sum(
i < 9 or 13 < i < 32 or 126 < i
for i in six.iterbytes(s[:100])