From ab7e2857cc9095c4cee8ca9b569c16516aa520ba Mon Sep 17 00:00:00 2001 From: Aldo Cortesi Date: Tue, 14 Apr 2015 15:14:36 +1200 Subject: [PATCH] New get_cookies for HttpResponse --- libmproxy/protocol/http.py | 27 +++++++++--------- test/test_flow.py | 54 ------------------------------------ test/test_protocol_http.py | 56 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 67 deletions(-) diff --git a/libmproxy/protocol/http.py b/libmproxy/protocol/http.py index cd9458f20..da8eaa010 100644 --- a/libmproxy/protocol/http.py +++ b/libmproxy/protocol/http.py @@ -902,20 +902,21 @@ class HTTPResponse(HTTPMessage): self.headers["set-cookie"] = c def get_cookies(self): - cookie_headers = self.headers.get("set-cookie") - if not cookie_headers: - return None + """ + Get the contents of all Set-Cookie headers. - cookies = [] - for header in cookie_headers: - pairs = [pair.partition("=") for pair in header.split(';')] - cookie_name = pairs[0][0] # the key of the first key/value pairs - cookie_value = pairs[0][2] # the value of the first key/value pairs - cookie_parameters = { - key.strip().lower(): value.strip() for key, sep, value in pairs[1:] - } - cookies.append((cookie_name, (cookie_value, cookie_parameters))) - return dict(cookies) + Returns a possibly empty ODict, where keys are cookie name strings, + and values are [value, attr] lists. Value is a string, and attr is + an ODictCaseless containing cookie attributes. Within attrs, unary + attributes (e.g. HTTPOnly) are indicated by a Null value. + """ + ret = [] + for header in self.headers["set-cookie"]: + v = http_cookies.parse_set_cookie_header(header) + if v: + name, value, attrs = v + ret.append([name, [value, attrs]]) + return odict.ODict(ret) class HTTPFlow(Flow): diff --git a/test/test_flow.py b/test/test_flow.py index 760f7d5b2..f5d069066 100644 --- a/test/test_flow.py +++ b/test/test_flow.py @@ -1148,60 +1148,6 @@ class TestResponse: result = len(r._assemble_headers()) assert result==44 - def test_get_cookies_none(self): - h = odict.ODictCaseless() - resp = tutils.tresp() - resp.headers = h - assert not resp.get_cookies() - - def test_get_cookies_simple(self): - h = odict.ODictCaseless() - h["Set-Cookie"] = ["cookiename=cookievalue"] - resp = tutils.tresp() - resp.headers = h - result = resp.get_cookies() - assert len(result)==1 - assert "cookiename" in result - assert result["cookiename"] == ("cookievalue", {}) - - def test_get_cookies_with_parameters(self): - h = odict.ODictCaseless() - h["Set-Cookie"] = ["cookiename=cookievalue;domain=example.com;expires=Wed Oct 21 16:29:41 2015;path=/; HttpOnly"] - resp = tutils.tresp() - resp.headers = h - result = resp.get_cookies() - assert len(result)==1 - assert "cookiename" in result - assert result["cookiename"][0] == "cookievalue" - assert len(result["cookiename"][1])==4 - assert result["cookiename"][1]["domain"]=="example.com" - assert result["cookiename"][1]["expires"]=="Wed Oct 21 16:29:41 2015" - assert result["cookiename"][1]["path"]=="/" - assert result["cookiename"][1]["httponly"]=="" - - def test_get_cookies_no_value(self): - h = odict.ODictCaseless() - h["Set-Cookie"] = ["cookiename=; Expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/"] - resp = tutils.tresp() - resp.headers = h - result = resp.get_cookies() - assert len(result)==1 - assert "cookiename" in result - assert result["cookiename"][0] == "" - assert len(result["cookiename"][1])==2 - - def test_get_cookies_twocookies(self): - h = odict.ODictCaseless() - h["Set-Cookie"] = ["cookiename=cookievalue","othercookie=othervalue"] - resp = tutils.tresp() - resp.headers = h - result = resp.get_cookies() - assert len(result)==2 - assert "cookiename" in result - assert result["cookiename"] == ("cookievalue", {}) - assert "othercookie" in result - assert result["othercookie"] == ("othervalue", {}) - def test_get_content_type(self): h = odict.ODictCaseless() h["Content-Type"] = ["text/plain"] diff --git a/test/test_protocol_http.py b/test/test_protocol_http.py index 11ab503be..0276cab77 100644 --- a/test/test_protocol_http.py +++ b/test/test_protocol_http.py @@ -230,6 +230,62 @@ class TestHTTPResponse: assert "foo" in repr(r) assert repr(tutils.tresp(content=CONTENT_MISSING)) + def test_get_cookies_none(self): + h = odict.ODictCaseless() + resp = tutils.tresp() + resp.headers = h + assert not resp.get_cookies() + + def test_get_cookies_simple(self): + h = odict.ODictCaseless() + h["Set-Cookie"] = ["cookiename=cookievalue"] + resp = tutils.tresp() + resp.headers = h + result = resp.get_cookies() + assert len(result)==1 + assert "cookiename" in result + assert result["cookiename"][0] == ["cookievalue", odict.ODict()] + + def test_get_cookies_with_parameters(self): + h = odict.ODictCaseless() + h["Set-Cookie"] = ["cookiename=cookievalue;domain=example.com;expires=Wed Oct 21 16:29:41 2015;path=/; HttpOnly"] + resp = tutils.tresp() + resp.headers = h + result = resp.get_cookies() + assert len(result)==1 + assert "cookiename" in result + assert result["cookiename"][0][0] == "cookievalue" + attrs = result["cookiename"][0][1] + assert len(attrs)==4 + assert attrs["domain"] == ["example.com"] + assert attrs["expires"] == ["Wed Oct 21 16:29:41 2015"] + assert attrs["path"] == ["/"] + assert attrs["httponly"] == [None] + + def test_get_cookies_no_value(self): + h = odict.ODictCaseless() + h["Set-Cookie"] = ["cookiename=; Expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/"] + resp = tutils.tresp() + resp.headers = h + result = resp.get_cookies() + assert len(result)==1 + assert "cookiename" in result + assert result["cookiename"][0][0] == "" + assert len(result["cookiename"][0][1])==2 + + def test_get_cookies_twocookies(self): + h = odict.ODictCaseless() + h["Set-Cookie"] = ["cookiename=cookievalue","othercookie=othervalue"] + resp = tutils.tresp() + resp.headers = h + result = resp.get_cookies() + assert len(result)==2 + assert "cookiename" in result + assert result["cookiename"][0] == ["cookievalue", odict.ODict()] + assert "othercookie" in result + assert result["othercookie"][0] == ["othervalue", odict.ODict()] + + class TestHTTPFlow(object): def test_repr(self):