Skip to content

Commit

Permalink
Convert everything from META to headers
Browse files Browse the repository at this point in the history
  • Loading branch information
albertyw committed Jan 13, 2023
1 parent 4784e2a commit bb4df5b
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 49 deletions.
4 changes: 2 additions & 2 deletions project/tests/test_config_long_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class TestLongRequestUrl(TestCase):
def test_no_long_url(self):
url = '1234567890' * 19 # 190-character URL
mock_request = Mock()
mock_request.META = {'CONTENT_TYPE': 'text/plain'}
mock_request.headers = {'content-type': 'text/plain'}
mock_request.GET = {}
mock_request.path = url
mock_request.method = 'get'
Expand All @@ -20,7 +20,7 @@ def test_no_long_url(self):
def test_long_url(self):
url = '1234567890' * 200 # 2000-character URL
mock_request = Mock()
mock_request.META = {'CONTENT_TYPE': 'text/plain'}
mock_request.headers = {'content-type': 'text/plain'}
mock_request.GET = {}
mock_request.method = 'get'
mock_request.path = url
Expand Down
12 changes: 4 additions & 8 deletions project/tests/test_config_max_body_size.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class TestMaxBodySizeRequest(TestCase):
def test_no_max_request(self):
SilkyConfig().SILKY_MAX_REQUEST_BODY_SIZE = -1
mock_request = Mock()
mock_request.META = {'CONTENT_TYPE': 'text/plain'}
mock_request.headers = {'content-type': 'text/plain'}
mock_request.GET = {}
mock_request.path = reverse('silk:requests')
mock_request.method = 'get'
Expand All @@ -25,7 +25,7 @@ def test_no_max_request(self):
def test_max_request(self):
SilkyConfig().SILKY_MAX_REQUEST_BODY_SIZE = 10 # 10kb
mock_request = Mock()
mock_request.META = {'CONTENT_TYPE': 'text/plain'}
mock_request.headers = {'content-type': 'text/plain'}
mock_request.GET = {}
mock_request.method = 'get'
mock_request.body = b'a' * 1024 * 100 # 100kb
Expand All @@ -42,9 +42,7 @@ def setUp(self):
def test_no_max_response(self):
SilkyConfig().SILKY_MAX_RESPONSE_BODY_SIZE = -1
mock_response = Mock()
headers = {'CONTENT_TYPE': 'text/plain'}
mock_response.get = headers.get
mock_response.headers = headers
mock_response.headers = {'content-type': 'text/plain'}
mock_response.content = b'a' * 1000 # 1000 bytes?
mock_response.status_code = 200
response_model = ResponseModelFactory(mock_response).construct_response_model()
Expand All @@ -53,9 +51,7 @@ def test_no_max_response(self):
def test_max_response(self):
SilkyConfig().SILKY_MAX_RESPONSE_BODY_SIZE = 10 # 10kb
mock_response = Mock()
headers = {'CONTENT_TYPE': 'text/plain'}
mock_response.get = headers.get
mock_response.headers = headers
mock_response.headers = {'content-type': 'text/plain'}
mock_response.content = b'a' * 1024 * 100 # 100kb
mock_response.status_code = 200
response_model = ResponseModelFactory(mock_response).construct_response_model()
Expand Down
25 changes: 12 additions & 13 deletions project/tests/test_encoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

from silk.model_factory import RequestModelFactory, ResponseModelFactory

DJANGO_META_CONTENT_TYPE = 'CONTENT_TYPE'
HTTP_CONTENT_TYPE = 'Content-Type'


Expand All @@ -16,41 +15,41 @@ class TestEncodingForRequests(TestCase):

def test_utf_plain(self):
mock_request = Mock()
mock_request.META = {DJANGO_META_CONTENT_TYPE: 'text/plain; charset=UTF-8'}
mock_request.headers = {HTTP_CONTENT_TYPE: 'text/plain; charset=UTF-8'}
mock_request.body = '语'
mock_request.get = mock_request.META.get
mock_request.get = mock_request.headers.get
factory = RequestModelFactory(mock_request)
body, raw_body = factory.body()
self.assertFalse(body)
self.assertEqual(raw_body, mock_request.body)

def test_plain(self):
mock_request = Mock()
mock_request.META = {DJANGO_META_CONTENT_TYPE: 'text/plain'}
mock_request.headers = {HTTP_CONTENT_TYPE: 'text/plain'}
mock_request.body = 'sdfsdf'
mock_request.get = mock_request.META.get
mock_request.get = mock_request.headers.get
factory = RequestModelFactory(mock_request)
body, raw_body = factory.body()
self.assertFalse(body)
self.assertEqual(raw_body, mock_request.body)

def test_utf_json_not_encoded(self):
mock_request = Mock()
mock_request.META = {DJANGO_META_CONTENT_TYPE: 'application/json; charset=UTF-8'}
mock_request.headers = {HTTP_CONTENT_TYPE: 'application/json; charset=UTF-8'}
d = {'x': '语'}
mock_request.body = json.dumps(d)
mock_request.get = mock_request.META.get
mock_request.get = mock_request.headers.get
factory = RequestModelFactory(mock_request)
body, raw_body = factory.body()
self.assertDictEqual(json.loads(body), d)
self.assertEqual(raw_body, mock_request.body)

def test_utf_json_encoded(self):
mock_request = Mock()
mock_request.META = {DJANGO_META_CONTENT_TYPE: 'application/json; charset=UTF-8'}
mock_request.headers = {HTTP_CONTENT_TYPE: 'application/json; charset=UTF-8'}
d = {'x': '语'}
mock_request.body = json.dumps(d).encode('UTF-8')
mock_request.get = mock_request.META.get
mock_request.get = mock_request.headers.get
factory = RequestModelFactory(mock_request)
body, raw_body = factory.body()
self.assertDictEqual(json.loads(body), d)
Expand All @@ -59,21 +58,21 @@ def test_utf_json_encoded(self):
def test_utf_json_encoded_no_charset(self):
"""default to UTF-8"""
mock_request = Mock()
mock_request.META = {DJANGO_META_CONTENT_TYPE: 'application/json'}
mock_request.headers = {HTTP_CONTENT_TYPE: 'application/json'}
d = {'x': '语'}
mock_request.body = json.dumps(d).encode('UTF-8')
mock_request.get = mock_request.META.get
mock_request.get = mock_request.headers.get
factory = RequestModelFactory(mock_request)
body, raw_body = factory.body()
self.assertDictEqual(json.loads(body), d)
self.assertEqual(raw_body, mock_request.body.decode('UTF-8'))

def test_invalid_encoding_json(self):
mock_request = Mock()
mock_request.META = {DJANGO_META_CONTENT_TYPE: 'application/json; charset=asdas-8'}
mock_request.headers = {HTTP_CONTENT_TYPE: 'application/json; charset=asdas-8'}
d = {'x': '语'}
mock_request.body = json.dumps(d).encode('UTF-8')
mock_request.get = mock_request.META.get
mock_request.get = mock_request.headers.get
factory = RequestModelFactory(mock_request)
body, raw_body = factory.body()
self.assertDictEqual(json.loads(body), d)
Expand Down
2 changes: 1 addition & 1 deletion project/tests/test_multipart_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class TestMultipartForms(TestCase):

def test_no_max_request(self):
mock_request = Mock()
mock_request.META = {'CONTENT_TYPE': multipart_form}
mock_request.headers = {'content-type': multipart_form}
mock_request.GET = {}
mock_request.path = reverse('silk:requests')
mock_request.method = 'post'
Expand Down
17 changes: 8 additions & 9 deletions project/tests/test_sensitive_data_in_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from silk.config import SilkyConfig
from silk.model_factory import RequestModelFactory

DJANGO_META_CONTENT_TYPE = 'CONTENT_TYPE'
HTTP_CONTENT_TYPE = 'Content-Type'
CLEANSED = RequestModelFactory.CLEANSED_SUBSTITUTE
DEFAULT_SENSITIVE_KEYS = {'username', 'api', 'token', 'key', 'secret', 'password', 'signature'}
Expand Down Expand Up @@ -130,9 +129,9 @@ class TestEncodingForRequests(TestCase):

def test_password_in_body(self):
mock_request = Mock()
mock_request.META = {DJANGO_META_CONTENT_TYPE: 'text/plain'}
mock_request.headers = {HTTP_CONTENT_TYPE: 'text/plain'}
mock_request.body = 'username=test_username&unmasked=testunmasked&password=testpassword'
mock_request.get = mock_request.META.get
mock_request.get = mock_request.headers.get
factory = RequestModelFactory(mock_request)
body, raw_body = factory.body()

Expand All @@ -144,11 +143,11 @@ def test_password_in_body(self):

def test_password_in_json(self):
mock_request = Mock()
mock_request.META = {DJANGO_META_CONTENT_TYPE: 'application/json; charset=UTF-8'}
mock_request.headers = {HTTP_CONTENT_TYPE: 'application/json; charset=UTF-8'}
d = {'x': 'testunmasked', 'username': 'test_username', 'password': 'testpassword',
'prefixed-secret': 'testsecret'}
mock_request.body = json.dumps(d)
mock_request.get = mock_request.META.get
mock_request.get = mock_request.headers.get
factory = RequestModelFactory(mock_request)
body, raw_body = factory.body()
self.assertIn('testunmasked', raw_body)
Expand All @@ -167,13 +166,13 @@ def test_password_in_json(self):

def test_password_in_batched_json(self):
mock_request = Mock()
mock_request.META = {DJANGO_META_CONTENT_TYPE: 'application/json; charset=UTF-8'}
mock_request.headers = {HTTP_CONTENT_TYPE: 'application/json; charset=UTF-8'}
d = [
{'x': 'testunmasked', 'username': 'test_username', 'password': 'testpassword'},
{'x': 'testunmasked', 'username': 'test_username', 'password': 'testpassword'}
]
mock_request.body = json.dumps(d)
mock_request.get = mock_request.META.get
mock_request.get = mock_request.headers.get
factory = RequestModelFactory(mock_request)
body, raw_body = factory.body()
self.assertIn('testunmasked', raw_body)
Expand All @@ -192,9 +191,9 @@ def test_password_in_batched_json(self):

def test_authorization_header(self):
mock_request = Mock()
mock_request.META = {'HTTP_AUTHORIZATION': 'secret'}
mock_request.headers = {'HTTP_AUTHORIZATION': 'secret'}
mock_request.body = ''
mock_request.get = mock_request.META.get
mock_request.get = mock_request.headers.get
factory = RequestModelFactory(mock_request)
headers = factory.encoded_headers()
json_headers = json.loads(headers)
Expand Down
22 changes: 6 additions & 16 deletions silk/model_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,31 +70,21 @@ def __init__(self, request):
self.request = request

def content_type(self):
content_type = self.request.META.get('CONTENT_TYPE', '')
content_type = self.request.headers.get('content-type', '')
return _parse_content_type(content_type)

def encoded_headers(self):
"""
From Django docs (https://docs.djangoproject.com/en/2.0/ref/request-response/#httprequest-objects):
"With the exception of CONTENT_LENGTH and CONTENT_TYPE, as given above, any HTTP headers in the request are converted to
META keys by converting all characters to uppercase, replacing any hyphens with underscores and adding an HTTP_ prefix
to the name. So, for example, a header called X-Bender would be mapped to the META key HTTP_X_BENDER."
"""
headers = {}
sensitive_headers = {'AUTHORIZATION'}

for k, v in self.request.META.items():
if k.startswith('HTTP') or k in ('CONTENT_TYPE', 'CONTENT_LENGTH'):
splt = k.split('_')
if splt[0] == 'HTTP':
splt = splt[1:]
k = '-'.join(splt)
sensitive_headers = {'authorization'}

if k in sensitive_headers:
v = RequestModelFactory.CLEANSED_SUBSTITUTE
for k, v in self.request.headers.items():
if k in sensitive_headers:
v = RequestModelFactory.CLEANSED_SUBSTITUTE

headers[k] = v
headers[k] = v
if SilkyConfig().SILKY_HIDE_COOKIES:
try:
del headers['COOKIE']
Expand Down

0 comments on commit bb4df5b

Please sign in to comment.