aboutsummaryrefslogtreecommitdiffstats
path: root/netlib
diff options
context:
space:
mode:
authorAldo Cortesi <aldo@nullcube.com>2016-10-20 10:22:23 +1300
committerAldo Cortesi <aldo@nullcube.com>2016-10-20 10:22:23 +1300
commit1ecb25cdc10116c5341dc1024581365bec328b4e (patch)
tree47c7d18aaeca5453182f837ff326e113344c36d7 /netlib
parentf45f4e677e8cddba8160d1e4e02ca8a4515e3456 (diff)
downloadmitmproxy-1ecb25cdc10116c5341dc1024581365bec328b4e.tar.gz
mitmproxy-1ecb25cdc10116c5341dc1024581365bec328b4e.tar.bz2
mitmproxy-1ecb25cdc10116c5341dc1024581365bec328b4e.zip
mitmproxy.types.[basethread,multidict,serializable]
Diffstat (limited to 'netlib')
-rw-r--r--netlib/basethread.py14
-rw-r--r--netlib/basetypes.py32
-rw-r--r--netlib/certutils.py4
-rw-r--r--netlib/http/cookies.py2
-rw-r--r--netlib/http/headers.py2
-rw-r--r--netlib/http/message.py6
-rw-r--r--netlib/http/request.py2
-rw-r--r--netlib/http/response.py2
-rw-r--r--netlib/multidict.py298
-rw-r--r--netlib/tcp.py6
10 files changed, 12 insertions, 356 deletions
diff --git a/netlib/basethread.py b/netlib/basethread.py
deleted file mode 100644
index a3c81d19..00000000
--- a/netlib/basethread.py
+++ /dev/null
@@ -1,14 +0,0 @@
-import time
-import threading
-
-
-class BaseThread(threading.Thread):
- def __init__(self, name, *args, **kwargs):
- super().__init__(name=name, *args, **kwargs)
- self._thread_started = time.time()
-
- def _threadinfo(self):
- return "%s - age: %is" % (
- self.name,
- int(time.time() - self._thread_started)
- )
diff --git a/netlib/basetypes.py b/netlib/basetypes.py
deleted file mode 100644
index 49892ffc..00000000
--- a/netlib/basetypes.py
+++ /dev/null
@@ -1,32 +0,0 @@
-import abc
-
-
-class Serializable(metaclass=abc.ABCMeta):
- """
- Abstract Base Class that defines an API to save an object's state and restore it later on.
- """
-
- @classmethod
- @abc.abstractmethod
- def from_state(cls, state):
- """
- Create a new object from the given state.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def get_state(self):
- """
- Retrieve object state.
- """
- raise NotImplementedError()
-
- @abc.abstractmethod
- def set_state(self, state):
- """
- Set object state to the given state.
- """
- raise NotImplementedError()
-
- def copy(self):
- return self.from_state(self.get_state())
diff --git a/netlib/certutils.py b/netlib/certutils.py
index 6a97f99e..9cb8a40e 100644
--- a/netlib/certutils.py
+++ b/netlib/certutils.py
@@ -10,7 +10,7 @@ from pyasn1.codec.der.decoder import decode
from pyasn1.error import PyAsn1Error
import OpenSSL
-from netlib import basetypes
+from mitmproxy.types import serializable
# Default expiry must not be too long: https://github.com/mitmproxy/mitmproxy/issues/815
@@ -373,7 +373,7 @@ class _GeneralNames(univ.SequenceOf):
constraint.ValueSizeConstraint(1, 1024)
-class SSLCert(basetypes.Serializable):
+class SSLCert(serializable.Serializable):
def __init__(self, cert):
"""
diff --git a/netlib/http/cookies.py b/netlib/http/cookies.py
index cb816ca0..9f32fa5e 100644
--- a/netlib/http/cookies.py
+++ b/netlib/http/cookies.py
@@ -3,7 +3,7 @@ import email.utils
import re
import time
-from netlib import multidict
+from mitmproxy.types import multidict
"""
A flexible module for cookie parsing and manipulation.
diff --git a/netlib/http/headers.py b/netlib/http/headers.py
index 6c30d278..8fc0cd43 100644
--- a/netlib/http/headers.py
+++ b/netlib/http/headers.py
@@ -1,7 +1,7 @@
import re
import collections
-from netlib import multidict
+from mitmproxy.types import multidict
from mitmproxy.utils import strutils
# See also: http://lucumr.pocoo.org/2013/7/2/the-updated-guide-to-unicode/
diff --git a/netlib/http/message.py b/netlib/http/message.py
index 133a53ce..62c3aa38 100644
--- a/netlib/http/message.py
+++ b/netlib/http/message.py
@@ -4,7 +4,7 @@ from typing import Optional
from mitmproxy.utils import strutils
from netlib import encoding
-from netlib import basetypes
+from mitmproxy.types import serializable
from netlib.http import headers
@@ -17,7 +17,7 @@ def _always_bytes(x):
return strutils.always_bytes(x, "utf-8", "surrogateescape")
-class MessageData(basetypes.Serializable):
+class MessageData(serializable.Serializable):
def __eq__(self, other):
if isinstance(other, MessageData):
return self.__dict__ == other.__dict__
@@ -43,7 +43,7 @@ class MessageData(basetypes.Serializable):
return cls(**state)
-class Message(basetypes.Serializable):
+class Message(serializable.Serializable):
def __eq__(self, other):
if isinstance(other, Message):
return self.data == other.data
diff --git a/netlib/http/request.py b/netlib/http/request.py
index 3479fa4c..16b0c986 100644
--- a/netlib/http/request.py
+++ b/netlib/http/request.py
@@ -1,7 +1,7 @@
import re
import urllib
-from netlib import multidict
+from mitmproxy.types import multidict
from mitmproxy.utils import strutils
from netlib.http import multipart
from netlib.http import cookies
diff --git a/netlib/http/response.py b/netlib/http/response.py
index 12dba92a..4d1d5d24 100644
--- a/netlib/http/response.py
+++ b/netlib/http/response.py
@@ -1,7 +1,7 @@
import time
from email.utils import parsedate_tz, formatdate, mktime_tz
from mitmproxy.utils import human
-from netlib import multidict
+from mitmproxy.types import multidict
from netlib.http import cookies
from netlib.http import headers as nheaders
from netlib.http import message
diff --git a/netlib/multidict.py b/netlib/multidict.py
deleted file mode 100644
index 191d1cc6..00000000
--- a/netlib/multidict.py
+++ /dev/null
@@ -1,298 +0,0 @@
-from abc import ABCMeta, abstractmethod
-
-
-try:
- from collections.abc import MutableMapping
-except ImportError: # pragma: no cover
- from collections import MutableMapping # Workaround for Python < 3.3
-
-from netlib import basetypes
-
-
-class _MultiDict(MutableMapping, basetypes.Serializable, metaclass=ABCMeta):
- def __repr__(self):
- fields = (
- repr(field)
- for field in self.fields
- )
- return "{cls}[{fields}]".format(
- cls=type(self).__name__,
- fields=", ".join(fields)
- )
-
- @staticmethod
- @abstractmethod
- def _reduce_values(values):
- """
- If a user accesses multidict["foo"], this method
- reduces all values for "foo" to a single value that is returned.
- For example, HTTP headers are folded, whereas we will just take
- the first cookie we found with that name.
- """
-
- @staticmethod
- @abstractmethod
- def _kconv(key):
- """
- This method converts a key to its canonical representation.
- For example, HTTP headers are case-insensitive, so this method returns key.lower().
- """
-
- def __getitem__(self, key):
- values = self.get_all(key)
- if not values:
- raise KeyError(key)
- return self._reduce_values(values)
-
- def __setitem__(self, key, value):
- self.set_all(key, [value])
-
- def __delitem__(self, key):
- if key not in self:
- raise KeyError(key)
- key = self._kconv(key)
- self.fields = tuple(
- field for field in self.fields
- if key != self._kconv(field[0])
- )
-
- def __iter__(self):
- seen = set()
- for key, _ in self.fields:
- key_kconv = self._kconv(key)
- if key_kconv not in seen:
- seen.add(key_kconv)
- yield key
-
- def __len__(self):
- return len(set(self._kconv(key) for key, _ in self.fields))
-
- def __eq__(self, other):
- if isinstance(other, MultiDict):
- return self.fields == other.fields
- return False
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
- def get_all(self, key):
- """
- Return the list of all values for a given key.
- If that key is not in the MultiDict, the return value will be an empty list.
- """
- key = self._kconv(key)
- return [
- value
- for k, value in self.fields
- if self._kconv(k) == key
- ]
-
- def set_all(self, key, values):
- """
- Remove the old values for a key and add new ones.
- """
- key_kconv = self._kconv(key)
-
- new_fields = []
- for field in self.fields:
- if self._kconv(field[0]) == key_kconv:
- if values:
- new_fields.append(
- (field[0], values.pop(0))
- )
- else:
- new_fields.append(field)
- while values:
- new_fields.append(
- (key, values.pop(0))
- )
- self.fields = tuple(new_fields)
-
- def add(self, key, value):
- """
- Add an additional value for the given key at the bottom.
- """
- self.insert(len(self.fields), key, value)
-
- def insert(self, index, key, value):
- """
- Insert an additional value for the given key at the specified position.
- """
- item = (key, value)
- self.fields = self.fields[:index] + (item,) + self.fields[index:]
-
- def keys(self, multi=False):
- """
- Get all keys.
-
- Args:
- multi(bool):
- If True, one key per value will be returned.
- If False, duplicate keys will only be returned once.
- """
- return (
- k
- for k, _ in self.items(multi)
- )
-
- def values(self, multi=False):
- """
- Get all values.
-
- Args:
- multi(bool):
- If True, all values will be returned.
- If False, only the first value per key will be returned.
- """
- return (
- v
- for _, v in self.items(multi)
- )
-
- def items(self, multi=False):
- """
- Get all (key, value) tuples.
-
- Args:
- multi(bool):
- If True, all (key, value) pairs will be returned
- If False, only the first (key, value) pair per unique key will be returned.
- """
- if multi:
- return self.fields
- else:
- return super().items()
-
- def collect(self):
- """
- Returns a list of (key, value) tuples, where values are either
- singular if there is only one matching item for a key, or a list
- if there are more than one. The order of the keys matches the order
- in the underlying fields list.
- """
- coll = []
- for key in self:
- values = self.get_all(key)
- if len(values) == 1:
- coll.append([key, values[0]])
- else:
- coll.append([key, values])
- return coll
-
- def to_dict(self):
- """
- Get the MultiDict as a plain Python dict.
- Keys with multiple values are returned as lists.
-
- Example:
-
- .. code-block:: python
-
- # Simple dict with duplicate values.
- >>> d = MultiDict([("name", "value"), ("a", False), ("a", 42)])
- >>> d.to_dict()
- {
- "name": "value",
- "a": [False, 42]
- }
- """
- return {
- k: v for k, v in self.collect()
- }
-
- def get_state(self):
- return self.fields
-
- def set_state(self, state):
- self.fields = tuple(tuple(x) for x in state)
-
- @classmethod
- def from_state(cls, state):
- return cls(state)
-
-
-class MultiDict(_MultiDict):
- def __init__(self, fields=()):
- super().__init__()
- self.fields = tuple(
- tuple(i) for i in fields
- )
-
- @staticmethod
- def _reduce_values(values):
- return values[0]
-
- @staticmethod
- def _kconv(key):
- return key
-
-
-class ImmutableMultiDict(MultiDict, metaclass=ABCMeta):
- def _immutable(self, *_):
- raise TypeError('{} objects are immutable'.format(self.__class__.__name__))
-
- __delitem__ = set_all = insert = _immutable
-
- def __hash__(self):
- return hash(self.fields)
-
- def with_delitem(self, key):
- """
- Returns:
- An updated ImmutableMultiDict. The original object will not be modified.
- """
- ret = self.copy()
- # FIXME: This is filthy...
- super(ImmutableMultiDict, ret).__delitem__(key)
- return ret
-
- def with_set_all(self, key, values):
- """
- Returns:
- An updated ImmutableMultiDict. The original object will not be modified.
- """
- ret = self.copy()
- # FIXME: This is filthy...
- super(ImmutableMultiDict, ret).set_all(key, values)
- return ret
-
- def with_insert(self, index, key, value):
- """
- Returns:
- An updated ImmutableMultiDict. The original object will not be modified.
- """
- ret = self.copy()
- # FIXME: This is filthy...
- super(ImmutableMultiDict, ret).insert(index, key, value)
- return ret
-
-
-class MultiDictView(_MultiDict):
- """
- The MultiDictView provides the MultiDict interface over calculated data.
- The view itself contains no state - data is retrieved from the parent on
- request, and stored back to the parent on change.
- """
- def __init__(self, getter, setter):
- self._getter = getter
- self._setter = setter
- super().__init__()
-
- @staticmethod
- def _kconv(key):
- # All request-attributes are case-sensitive.
- return key
-
- @staticmethod
- def _reduce_values(values):
- # We just return the first element if
- # multiple elements exist with the same key.
- return values[0]
-
- @property
- def fields(self):
- return self._getter()
-
- @fields.setter
- def fields(self, value):
- self._setter(value)
diff --git a/netlib/tcp.py b/netlib/tcp.py
index aed79388..4fde657f 100644
--- a/netlib/tcp.py
+++ b/netlib/tcp.py
@@ -19,9 +19,9 @@ from OpenSSL import SSL
from netlib import certutils
from netlib import version_check
-from netlib import basetypes
+from mitmproxy.types import serializable
from netlib import exceptions
-from netlib import basethread
+from mitmproxy.types import basethread
# This is a rather hackish way to make sure that
# the latest version of pyOpenSSL is actually installed.
@@ -292,7 +292,7 @@ class Reader(_FileLike):
raise NotImplementedError("Can only peek into (pyOpenSSL) sockets")
-class Address(basetypes.Serializable):
+class Address(serializable.Serializable):
"""
This class wraps an IPv4/IPv6 tuple to provide named attributes and