Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions openedx/core/lib/request_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
# .. toggle_name: request_utils.capture_cookie_sizes
# .. toggle_implementation: WaffleFlag
# .. toggle_default: False
# .. toggle_description: Enables capturing of cookie sizes for monitoring purposes. This can be useful for tracking
# down large cookies and avoiding hitting limits on the total size of cookies. See the CookieMonitoringMiddleware
# docstring for details on the monitoring custom attributes that will be set.
# .. toggle_description: Enables more detailed capturing of cookie sizes for monitoring purposes. This can be useful for tracking
# down large cookies if requests are nearing limits on the total size of cookies. See the
# CookieMonitoringMiddleware docstring for details on the monitoring custom attributes that will be set.
# .. toggle_warnings: Enabling this flag will add a number of custom attributes, and could adversely affect other
# monitoring. Only enable temporarily, or lower TOP_N_COOKIES_CAPTURED and TOP_N_COOKIE_GROUPS_CAPTURED django
# settings to capture less data.
Expand Down Expand Up @@ -123,6 +123,10 @@ def process_request(self, request):

Attributes that are added by this middleware:

cookies.header.size: The total size in bytes of the cookie header

If CAPTURE_COOKIE_SIZES is enabled, additional attributes will be added:

cookies.<N>.name: The name of the Nth largest cookie
cookies.<N>.size: The size of the Nth largest cookie
cookies..group.<N>.name: The name of the Nth largest cookie.
Expand All @@ -141,6 +145,10 @@ def process_request(self, request):
- TOP_N_COOKIE_GROUPS_CAPTURED

"""

raw_header_cookie = request.META.get('HTTP_COOKIE', '')
set_custom_attribute('cookies.header.size', len(raw_header_cookie.encode('utf-8')))

if not CAPTURE_COOKIE_SIZES.is_enabled():
return

Expand Down
60 changes: 51 additions & 9 deletions openedx/core/lib/tests/test_request_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,32 @@ def assertCourseIdFieldsMatch(self, course_id, org, course, run):
assert course_id.course == course
assert course_id.run == run

@patch("openedx.core.lib.request_utils.CAPTURE_COOKIE_SIZES")
@patch("openedx.core.lib.request_utils.set_custom_attribute")
def test_basic_cookie_monitoring(self, mock_set_custom_attribute, mock_capture_cookie_sizes):
mock_capture_cookie_sizes.is_enabled.return_value = False
middleware = CookieMonitoringMiddleware()

cookies_dict = {'a': 'b'}

factory = RequestFactory()
for name, value in cookies_dict.items():
factory.cookies[name] = value

mock_request = factory.request()

middleware.process_request(mock_request)

mock_set_custom_attribute.assert_called_once_with('cookies.header.size', 3)

@patch("openedx.core.lib.request_utils.CAPTURE_COOKIE_SIZES")
@patch("openedx.core.lib.request_utils.set_custom_attribute")
def test_cookie_monitoring(self, mock_set_custom_attribute, mock_capture_cookie_sizes):

mock_capture_cookie_sizes.is_enabled.return_value = True
middleware = CookieMonitoringMiddleware()

mock_request = Mock()
mock_request.COOKIES = {
cookies_dict = {
"a": "." * 100,
"_b": "." * 13,
"_c_": "." * 13,
Expand All @@ -117,6 +134,12 @@ def test_cookie_monitoring(self, mock_set_custom_attribute, mock_capture_cookie_
"d": "." * 3,
}

factory = RequestFactory()
for name, value in cookies_dict.items():
factory.cookies[name] = value

mock_request = factory.request()

middleware.process_request(mock_request)

mock_set_custom_attribute.assert_has_calls([
Expand Down Expand Up @@ -147,6 +170,7 @@ def test_cookie_monitoring(self, mock_set_custom_attribute, mock_capture_cookie_
call('cookies_total_size', 192),
call('cookies_unaccounted_size', 3),
call('cookies_total_num', 9),
call('cookies.header.size', 238)
], any_order=True)

@patch("openedx.core.lib.request_utils.CAPTURE_COOKIE_SIZES")
Expand All @@ -156,13 +180,18 @@ def test_cookie_monitoring_max_group(self, mock_set_custom_attribute, mock_captu
mock_capture_cookie_sizes.is_enabled.return_value = True
middleware = CookieMonitoringMiddleware()

mock_request = Mock()
mock_request.COOKIES = {
cookies_dict = {
"a": "." * 10,
"b_a": "." * 15,
"b_c": "." * 20,
}

factory = RequestFactory()
for name, value in cookies_dict.items():
factory.cookies[name] = value

mock_request = factory.request()

middleware.process_request(mock_request)

mock_set_custom_attribute.assert_has_calls([
Expand All @@ -188,12 +217,20 @@ def test_cookie_monitoring_no_cookies(self, mock_set_custom_attribute, mock_capt
mock_capture_cookie_sizes.is_enabled.return_value = True
middleware = CookieMonitoringMiddleware()

mock_request = Mock()
mock_request.COOKIES = {}
cookies_dict = {}

factory = RequestFactory()
for name, value in cookies_dict.items():
factory.cookies[name] = value

mock_request = factory.request()

middleware.process_request(mock_request)

mock_set_custom_attribute.assert_has_calls([call('cookies_total_size', 0)], any_order=True)
mock_set_custom_attribute.assert_has_calls([
call('cookies_total_size', 0),
call('cookies.header.size', 0)
], any_order=True)

@patch("openedx.core.lib.request_utils.CAPTURE_COOKIE_SIZES")
@patch("openedx.core.lib.request_utils.set_custom_attribute")
Expand All @@ -202,12 +239,17 @@ def test_cookie_monitoring_no_groups(self, mock_set_custom_attribute, mock_captu
mock_capture_cookie_sizes.is_enabled.return_value = True
middleware = CookieMonitoringMiddleware()

mock_request = Mock()
mock_request.COOKIES = {
cookies_dict = {
"a": "." * 10,
"b": "." * 15,
}

factory = RequestFactory()
for name, value in cookies_dict.items():
factory.cookies[name] = value

mock_request = factory.request()

middleware.process_request(mock_request)

mock_set_custom_attribute.assert_has_calls([
Expand Down