Skip to content

Commit 8639728

Browse files
author
David Erb
committed
adds raw cookie parser
1 parent 537f8ba commit 8639728

File tree

8 files changed

+142
-12
lines changed

8 files changed

+142
-12
lines changed

src/dls_servbase_api/aiohttp_client.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,12 @@ async def client_get_info(self):
9393
return await response.json()
9494

9595
# ----------------------------------------------------------------------------------------
96-
async def client_protocolj(self, request_object, cookies=None):
96+
async def client_protocolj(
97+
self,
98+
request_object,
99+
cookies=None,
100+
headers=None,
101+
):
97102
""""""
98103
await self._establish_client_session()
99104

@@ -104,6 +109,7 @@ async def client_protocolj(self, request_object, cookies=None):
104109
f"{self.__client_netloc}/protocolj",
105110
json=request_object,
106111
cookies=cookies,
112+
headers=headers,
107113
) as response:
108114
if response.status == 200:
109115
response_json = await response.json()

src/dls_servbase_lib/base_aiohttp.py

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from dls_mainiac_lib.mainiac import Mainiac
1818
from dls_multiconf_lib.multiconfs import multiconfs_get_default, multiconfs_has_default
1919
from dls_utilpack.callsign import callsign
20+
from dls_utilpack.describe import describe
2021
from dls_utilpack.explain import explain
2122
from dls_utilpack.global_signals import global_sigint
2223
from dls_utilpack.modify_process_title import modify_process_title
@@ -25,6 +26,7 @@
2526

2627
from dls_servbase_api.aiohttp_client import AiohttpClient # noqa: I001
2728
from dls_servbase_api.constants import Keywords # noqa: I001
29+
from dls_servbase_lib.cookies.cookie_parser import CookieParser
2830
from dls_servbase_lib.cookies.cookies import Cookies
2931

3032
logger = logging.getLogger(__name__)
@@ -507,11 +509,30 @@ async def register_cookies(self, opaque, web_request, cookie_names):
507509

508510
logger.debug(f"[COOKOFF] registering cookies {cookie_names}")
509511

512+
# We have to parse the Cookie header ourselves from the raw
513+
# since web_request.cookies uses SimpleCookie which doesn't work for
514+
# Chrome's ill-formed: CookieControl={"necessaryCookies":[]
515+
raw_header_cookie = web_request.headers.get("Cookie")
516+
parsed_cookies = CookieParser().parse_raw(raw_header_cookie)
517+
logger.debug(describe("[COOKOFF] parsed_cookies are", parsed_cookies))
518+
519+
# from http import cookies
520+
521+
# http_cookies = cookies.SimpleCookie()
522+
# http_cookies.load(web_request.headers["Cookie"])
523+
# logger.debug(
524+
# describe(
525+
# "[COOKOFF] http_cookies keys",
526+
# list(http_cookies.keys()),
527+
# )
528+
# )
529+
510530
# The caller gives the list of cookies that are interesting.
511531
for cookie_name in cookie_names:
512532
# We have a uuid for this cookie name already?
513-
if cookie_name in web_request.cookies:
514-
_uuid = web_request.cookies[cookie_name]
533+
_uuid = parsed_cookies.get(cookie_name)
534+
535+
if _uuid is not None:
515536
logger.debug(
516537
f"[COOKOFF] registering cookie {cookie_name} from existing uuid {_uuid}"
517538
)
@@ -731,10 +752,17 @@ def client_url(self):
731752
return self.__callsign_url
732753

733754
# ----------------------------------------------------------------------------------------
734-
async def client_protocolj(self, request_object, cookies=None):
755+
async def client_protocolj(
756+
self,
757+
request_object,
758+
cookies=None,
759+
headers=None,
760+
):
735761
""""""
736762
return await self.__aiohttp_client.client_protocolj(
737-
request_object, cookies=cookies
763+
request_object,
764+
cookies=cookies,
765+
headers=headers,
738766
)
739767

740768
# ----------------------------------------------------------------------------------------
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import logging
2+
from http import cookies
3+
from typing import Dict, Optional
4+
5+
logger = logging.getLogger(__name__)
6+
7+
8+
class CookieParser:
9+
10+
# ----------------------------------------------------------------------------------------
11+
def parse_raw(self, raw: Optional[str]) -> Dict:
12+
""" """
13+
14+
cookie_dict = {}
15+
if raw is not None:
16+
items = raw.split(";")
17+
18+
for item in items:
19+
parts = item.split("=", 1)
20+
21+
if len(parts) == 2:
22+
cookie_dict[parts[0].strip()] = parts[1].strip()
23+
24+
return cookie_dict
25+
26+
# ----------------------------------------------------------------------------------------
27+
def __parse_raw_WITH_HTTP_COOKIES(self, raw: str) -> Dict:
28+
"""
29+
This doesn't work when raw is like: 'Something="{something}"; X=Y;'
30+
"""
31+
32+
http_cookies: cookies.SimpleCookie = cookies.SimpleCookie()
33+
34+
http_cookies.load(raw)
35+
36+
cookie_dict = {}
37+
for key, morsel in http_cookies.items():
38+
cookie_dict[key] = morsel.value
39+
40+
return cookie_dict

src/dls_servbase_lib/guis/constants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ class Commands:
1010

1111

1212
class Cookies:
13-
TABS_MANAGER = "dls_servbase_guis::cookies::tabs_manager"
13+
TABS_MANAGER = "DLS_SERVBASE_TABS_MANAGER"

tests/configurations/sqlite.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ logging_settings:
55
enabled: True
66
verbose: True
77
filters:
8-
markers:
8+
Xmarkers:
99
- "[RELCOOK]"
1010
- "[COOKSEL]"
1111
- "[COOKOFF]"

tests/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def logging_setup():
4343
logging.getLogger("dls_servbase_lib.things").setLevel("INFO")
4444

4545
# Messages about starting and stopping services.
46-
logging.getLogger("dls_servbase_lib.base_aiohttp").setLevel("INFO")
46+
# logging.getLogger("dls_servbase_lib.base_aiohttp").setLevel("INFO")
4747

4848
# All dls_servbase database sql commands.
4949
# logging.getLogger("dls_servbase_lib.databases.aiosqlite").setLevel("INFO")

tests/test_gui.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ async def _main_coroutine(self, constants, output_directory):
7171
ProtocoljKeywords.ENABLE_COOKIES: [Cookies.TABS_MANAGER],
7272
}
7373

74+
logger.debug("---------------------- making request 1 --------------------")
7475
response = await dls_servbase_guis_get_default().client_protocolj(
7576
load_tabs_request, cookies={}
7677
)
@@ -84,8 +85,8 @@ async def _main_coroutine(self, constants, output_directory):
8485
cookies = response["__cookies"]
8586
assert Cookies.TABS_MANAGER in cookies
8687

87-
# Use the cookie name in the next requests.
88-
cookie_uuid = cookies[Cookies.TABS_MANAGER]
88+
# Use the tabs manager cookie value in the next requests.
89+
cookie_uuid = cookies[Cookies.TABS_MANAGER].value
8990

9091
# --------------------------------------------------------------------
9192
# Select a tab.
@@ -97,15 +98,22 @@ async def _main_coroutine(self, constants, output_directory):
9798
Keywords.TAB_ID: "123",
9899
}
99100

101+
logger.debug("---------------------- making request 2 --------------------")
100102
response = await dls_servbase_guis_get_default().client_protocolj(
101103
select_tab_request, cookies={Cookies.TABS_MANAGER: cookie_uuid}
102104
)
103105

104106
# --------------------------------------------------------------------
105107
# Load tabs again, this time we should get the saved tab_id.
106108

109+
logger.debug("---------------------- making request 3 --------------------")
110+
# Put a deliberately funky cookie string into the header.
111+
raw_cookie_header = (
112+
'BadCookie={"something"}; ' + f"{Cookies.TABS_MANAGER} = {cookie_uuid};"
113+
)
107114
response = await dls_servbase_guis_get_default().client_protocolj(
108-
load_tabs_request, cookies={Cookies.TABS_MANAGER: cookie_uuid}
115+
load_tabs_request,
116+
headers={"Cookie": raw_cookie_header},
109117
)
110118

111119
logger.debug(describe("second load_tabs response", response))
@@ -122,16 +130,34 @@ async def _main_coroutine(self, constants, output_directory):
122130
Keywords.TAB_ID: "456",
123131
}
124132

133+
logger.debug("---------------------- making request 4 --------------------")
125134
response = await dls_servbase_guis_get_default().client_protocolj(
126-
select_tab_request, cookies={Cookies.TABS_MANAGER: cookie_uuid}
135+
select_tab_request,
136+
cookies={Cookies.TABS_MANAGER: cookie_uuid},
137+
)
138+
139+
# --------------------------------------------------------------------
140+
# Load tabs again, this time we should get the updated tab_id.
141+
142+
logger.debug("---------------------- making request 5 --------------------")
143+
response = await dls_servbase_guis_get_default().client_protocolj(
144+
load_tabs_request,
145+
cookies={Cookies.TABS_MANAGER: cookie_uuid},
127146
)
128147

148+
logger.debug(describe("third load_tabs response", response))
149+
assert Keywords.TAB_ID in response
150+
assert response[Keywords.TAB_ID] == "456"
151+
129152
# --------------------------------------------------------------------
130153
# Write a text file and fetch it through the http server.
131154
filename = "test.html"
132155
contents = "some test html"
133156
with open(f"{output_directory}/{filename}", "wt") as file:
134157
file.write(contents)
158+
logger.debug(
159+
"---------------------- making request 6 (html file) --------------------"
160+
)
135161
text = await dls_servbase_guis_get_default().client_get_file(filename)
136162
# assert text == contents
137163

tests/test_parse_cookie.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import logging
2+
3+
# Utilities.
4+
from dls_utilpack.describe import describe
5+
6+
from dls_servbase_lib.cookies.cookie_parser import CookieParser
7+
8+
logger = logging.getLogger(__name__)
9+
10+
11+
class TestParseCookie:
12+
"""
13+
Test parsing a raw cookie value.
14+
"""
15+
16+
# ----------------------------------------------------------------------------------------
17+
def test(
18+
self,
19+
constants,
20+
logging_setup,
21+
output_directory,
22+
):
23+
""" """
24+
25+
part1 = 'CookieControl={"necessaryCookies":[],"optionalCookies":{"analytics":"accepted"},"statement":{"shown":true,"updated":"20/02/2019"},"consentDate":1684481396049,"consentExpiry":90,"interactedWith":true,"user":"6621E582-416C-4069-9604-A9A9C1EC3D1C"};'
26+
part2 = "_ga=GA1.3.145778769.1684481396; BXFLOW_RECENT_JOBS_UX=1975b4df-8d91-4e09-ab26-3f47aabe984d; BXFLOW_JOB_SUBMIT_UX=775a8760-7a81-4f2d-824c-067b89bf4561; BXFLOW_JOB_NEWS_UX=37bdfb1b-ceba-43e8-b108-9fb5ffb29186; BXFLOW_JOB_VARIABLES_UX=58c35196-47a0-4a82-9ecc-e96ec488899a; BXFLOW_JOB_DETAILS_UX=eb72189d-481d-4d9d-af81-4c900073e10d; BXFLOW_JOB_DATA_GRID_UX=a43220f9-c997-42dd-aee5-cd44048f5f20; BXFLOW_TABS_MANAGER=89353ec2-59e8-4d73-bbfc-2d249859227a"
27+
28+
cookies = CookieParser().parse_raw(part1 + " " + part2)
29+
30+
logger.debug(describe("[COOKOFF] cookies", cookies))

0 commit comments

Comments
 (0)