aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaximilian Hils <git@maximilianhils.com>2016-07-09 13:20:45 -0700
committerGitHub <noreply@github.com>2016-07-09 13:20:45 -0700
commitdc6266e08e58a2ec7a6660e125ddc585916f4dcd (patch)
tree967ae4b327074a93cb37d87876cd91c4cc976a5c
parent7efd63f94c5871ab6f93a1e39355cb37d9d6e107 (diff)
parent7eade1ef7c24b98567c1657973290aa5377b2719 (diff)
downloadmitmproxy-dc6266e08e58a2ec7a6660e125ddc585916f4dcd.tar.gz
mitmproxy-dc6266e08e58a2ec7a6660e125ddc585916f4dcd.tar.bz2
mitmproxy-dc6266e08e58a2ec7a6660e125ddc585916f4dcd.zip
Merge pull request #1324 from dufferzafar/sticky-cookies
Delete stickycookies when told by the server
-rw-r--r--mitmproxy/flow/modules.py18
-rw-r--r--netlib/http/cookies.py29
-rw-r--r--test/mitmproxy/test_flow.py16
-rw-r--r--test/netlib/http/test_cookies.py21
4 files changed, 77 insertions, 7 deletions
diff --git a/mitmproxy/flow/modules.py b/mitmproxy/flow/modules.py
index cba96fbc..ab41da8d 100644
--- a/mitmproxy/flow/modules.py
+++ b/mitmproxy/flow/modules.py
@@ -320,10 +320,20 @@ class StickyCookieState:
for name, (value, attrs) in f.response.cookies.items(multi=True):
# FIXME: We now know that Cookie.py screws up some cookies with
# valid RFC 822/1123 datetime specifications for expiry. Sigh.
- a = self.ckey(attrs, f)
- if self.domain_match(f.request.host, a[0]):
- b = attrs.with_insert(0, name, value)
- self.jar[a][name] = b
+ dom_port_path = self.ckey(attrs, f)
+
+ if self.domain_match(f.request.host, dom_port_path[0]):
+ if cookies.is_expired(attrs):
+ # Remove the cookie from jar
+ self.jar[dom_port_path].pop(name, None)
+
+ # If all cookies of a dom_port_path have been removed
+ # then remove it from the jar itself
+ if not self.jar[dom_port_path]:
+ self.jar.pop(dom_port_path, None)
+ else:
+ b = attrs.with_insert(0, name, value)
+ self.jar[dom_port_path][name] = b
def handle_request(self, f):
l = []
diff --git a/netlib/http/cookies.py b/netlib/http/cookies.py
index 768a85df..dd0af99c 100644
--- a/netlib/http/cookies.py
+++ b/netlib/http/cookies.py
@@ -1,7 +1,8 @@
import collections
+import email.utils
import re
+import time
-import email.utils
from netlib import multidict
"""
@@ -260,3 +261,29 @@ def refresh_set_cookie_header(c, delta):
if not ret:
raise ValueError("Invalid Cookie")
return ret
+
+
+def is_expired(cookie_attrs):
+ """
+ Determines whether a cookie has expired.
+
+ Returns: boolean
+ """
+
+ # See if 'expires' time is in the past
+ expires = False
+ if 'expires' in cookie_attrs:
+ e = email.utils.parsedate_tz(cookie_attrs["expires"])
+ if e:
+ exp_ts = email.utils.mktime_tz(e)
+ now_ts = time.time()
+ expires = exp_ts < now_ts
+
+ # or if Max-Age is 0
+ max_age = False
+ try:
+ max_age = int(cookie_attrs.get('Max-Age', 1)) == 0
+ except ValueError:
+ pass
+
+ return expires or max_age
diff --git a/test/mitmproxy/test_flow.py b/test/mitmproxy/test_flow.py
index bf7622f6..74b3f599 100644
--- a/test/mitmproxy/test_flow.py
+++ b/test/mitmproxy/test_flow.py
@@ -55,14 +55,16 @@ class TestStickyCookieState:
assert s.domain_match("google.com", ".google.com")
def test_response(self):
- c = "SSID=mooo; domain=.google.com, FOO=bar; Domain=.google.com; Path=/; " \
+ c = (
+ "SSID=mooo; domain=.google.com, FOO=bar; Domain=.google.com; Path=/; "
"Expires=Wed, 13-Jan-2021 22:23:01 GMT; Secure; "
+ )
s, f = self._response(c, "host")
assert not s.jar.keys()
s, f = self._response(c, "www.google.com")
- assert s.jar.keys()
+ assert list(s.jar.keys())[0] == ('.google.com', 80, '/')
s, f = self._response("SSID=mooo", "www.google.com")
assert list(s.jar.keys())[0] == ('www.google.com', 80, '/')
@@ -101,6 +103,16 @@ class TestStickyCookieState:
assert len(s.jar[googlekey]) == 1
assert list(s.jar[googlekey]["somecookie"].values())[0] == "newvalue"
+ def test_response_delete(self):
+ c = "duffer=zafar; Path=/", "www.google.com"
+
+ # Test that a cookie is be deleted
+ # by setting the expire time in the past
+ s, f = self._response(*c)
+ f.response.headers["Set-Cookie"] = "duffer=; Expires=Thu, 01-Jan-1970 00:00:00 GMT"
+ s.handle_response(f)
+ assert not s.jar.keys()
+
def test_request(self):
s, f = self._response("SSID=mooo", b"www.google.com")
assert "cookie" not in f.request.headers
diff --git a/test/netlib/http/test_cookies.py b/test/netlib/http/test_cookies.py
index 83b85656..17e21b94 100644
--- a/test/netlib/http/test_cookies.py
+++ b/test/netlib/http/test_cookies.py
@@ -245,3 +245,24 @@ def test_refresh_cookie():
assert cookies.refresh_set_cookie_header(c, 0)
c = "foo/bar=bla"
assert cookies.refresh_set_cookie_header(c, 0)
+
+
+def test_is_expired():
+ CA = cookies.CookieAttrs
+
+ # A cookie can be expired
+ # by setting the expire time in the past
+ assert cookies.is_expired(CA([("Expires", "Thu, 01-Jan-1970 00:00:00 GMT")]))
+
+ # or by setting Max-Age to 0
+ assert cookies.is_expired(CA([("Max-Age", "0")]))
+
+ # or both
+ assert cookies.is_expired(CA([("Expires", "Thu, 01-Jan-1970 00:00:00 GMT"), ("Max-Age", "0")]))
+
+ assert not cookies.is_expired(CA([("Expires", "Thu, 24-Aug-2063 00:00:00 GMT")]))
+ assert not cookies.is_expired(CA([("Max-Age", "1")]))
+ assert not cookies.is_expired(CA([("Expires", "Thu, 15-Jul-2068 00:00:00 GMT"), ("Max-Age", "1")]))
+
+ assert not cookies.is_expired(CA([("Max-Age", "nan")]))
+ assert not cookies.is_expired(CA([("Expires", "false")]))