aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mitmproxy/console/flowview.py14
-rw-r--r--netlib/http/message.py6
-rw-r--r--netlib/multidict.py6
-rw-r--r--test/netlib/http/test_message.py4
-rw-r--r--test/netlib/test_multidict.py14
5 files changed, 26 insertions, 18 deletions
diff --git a/mitmproxy/console/flowview.py b/mitmproxy/console/flowview.py
index ac9570ff..789066fc 100644
--- a/mitmproxy/console/flowview.py
+++ b/mitmproxy/console/flowview.py
@@ -189,15 +189,21 @@ class FlowView(tabs.Tabs):
limit = sys.maxsize
else:
limit = contentviews.VIEW_CUTOFF
+
+ flow_modify_cache_invalidation = hash((
+ message.raw_content,
+ message.headers.fields,
+ getattr(message, "path", None),
+ ))
return cache.get(
- self._get_content_view,
+ # We move message into this partial function as it is not hashable.
+ lambda *args: self._get_content_view(message, *args),
viewmode,
- message,
limit,
- message # Cache invalidation
+ flow_modify_cache_invalidation
)
- def _get_content_view(self, viewmode, message, max_lines, _):
+ def _get_content_view(self, message, viewmode, max_lines, _):
try:
content = message.content
diff --git a/netlib/http/message.py b/netlib/http/message.py
index 34709f0a..a86e7489 100644
--- a/netlib/http/message.py
+++ b/netlib/http/message.py
@@ -32,9 +32,6 @@ class MessageData(basetypes.Serializable):
def __ne__(self, other):
return not self.__eq__(other)
- def __hash__(self):
- return hash(frozenset(self.__dict__.items()))
-
def set_state(self, state):
for k, v in state.items():
if k == "headers":
@@ -77,9 +74,6 @@ class Message(basetypes.Serializable):
def __ne__(self, other):
return not self.__eq__(other)
- def __hash__(self):
- return hash(self.data) ^ 1
-
def get_state(self):
return self.data.get_state()
diff --git a/netlib/multidict.py b/netlib/multidict.py
index 51053ff6..e9fec155 100644
--- a/netlib/multidict.py
+++ b/netlib/multidict.py
@@ -79,9 +79,6 @@ class _MultiDict(MutableMapping, basetypes.Serializable):
def __ne__(self, other):
return not self.__eq__(other)
- def __hash__(self):
- return hash(self.fields)
-
def get_all(self, key):
"""
Return the list of all values for a given key.
@@ -241,6 +238,9 @@ class ImmutableMultiDict(MultiDict):
__delitem__ = set_all = insert = _immutable
+ def __hash__(self):
+ return hash(self.fields)
+
def with_delitem(self, key):
"""
Returns:
diff --git a/test/netlib/http/test_message.py b/test/netlib/http/test_message.py
index deebd6f2..7f93830e 100644
--- a/test/netlib/http/test_message.py
+++ b/test/netlib/http/test_message.py
@@ -71,10 +71,6 @@ class TestMessage(object):
assert resp != 0
- def test_hash(self):
- resp = tresp()
- assert hash(resp)
-
def test_serializable(self):
resp = tresp()
resp2 = http.Response.from_state(resp.get_state())
diff --git a/test/netlib/test_multidict.py b/test/netlib/test_multidict.py
index 038441e7..58ae0f98 100644
--- a/test/netlib/test_multidict.py
+++ b/test/netlib/test_multidict.py
@@ -45,7 +45,7 @@ class TestMultiDict(object):
assert md["foo"] == "bar"
with tutils.raises(KeyError):
- md["bar"]
+ assert md["bar"]
md_multi = TMultiDict(
[("foo", "a"), ("foo", "b")]
@@ -101,6 +101,15 @@ class TestMultiDict(object):
assert TMultiDict() != self._multi()
assert TMultiDict() != 42
+ def test_hash(self):
+ """
+ If a class defines mutable objects and implements an __eq__() method,
+ it should not implement __hash__(), since the implementation of hashable
+ collections requires that a key's hash value is immutable.
+ """
+ with tutils.raises(TypeError):
+ assert hash(TMultiDict())
+
def test_get_all(self):
md = self._multi()
assert md.get_all("foo") == ["bar"]
@@ -197,6 +206,9 @@ class TestImmutableMultiDict(object):
with tutils.raises(TypeError):
md.add("foo", "bar")
+ def test_hash(self):
+ assert hash(TImmutableMultiDict())
+
def test_with_delitem(self):
md = TImmutableMultiDict([("foo", "bar")])
assert md.with_delitem("foo").fields == ()