Skip to content

Commit

Permalink
Prevent path or view_name being longer than 190 characters
Browse files Browse the repository at this point in the history
MySQL index restrictions prevent us from having path or view_name be longer than 190 characters (see jazzband#38), but there is no logic in the Request object to enforce this limit when saving, so long URLs cause a 500 error.

Closes jazzband#179.
  • Loading branch information
smaccona committed Oct 26, 2018
1 parent 34ad9dd commit c7d7aee
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 0 deletions.
27 changes: 27 additions & 0 deletions project/tests/test_config_long_urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from django.test import TestCase
from mock import Mock
from silk.model_factory import RequestModelFactory


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.GET = {}
mock_request.path = url
mock_request.method = 'get'
request_model = RequestModelFactory(mock_request).construct_request_model()
self.assertEqual(request_model.path, url)

def test_long_url(self):
url = '1234567890' * 200 # 2000-character URL
mock_request = Mock()
mock_request.META = {'CONTENT_TYPE': 'text/plain'}
mock_request.GET = {}
mock_request.method = 'get'
mock_request.path = url
request_model = RequestModelFactory(mock_request).construct_request_model()
self.assertEqual(request_model.path, '%s...%s' % (url[:94], url[1907:]))
self.assertEqual(len(request_model.path), 190)
12 changes: 12 additions & 0 deletions silk/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ class Request(models.Model):
pyprofile = TextField(blank=True, default='')
prof_file = FileField(max_length=300, blank=True, storage=silk_storage)

# Useful method to create shortened copies of strings without losing start and end context
# Used to ensure path and view_name don't exceed 190 characters
def _shorten(self, string):
return '%s...%s' % (string[:94], string[len(string) - 93:])

@property
def total_meta_time(self):
return (self.meta_time or 0) + (self.meta_time_spent_queries or 0)
Expand Down Expand Up @@ -163,6 +168,13 @@ def save(self, *args, **kwargs):
interval = self.end_time - self.start_time
self.time_taken = interval.total_seconds() * 1000

# We can't save if either path or view_name exceed 190 characters
if self.path and len(self.path) > 190:
self.path = self._shorten(self.path)

if self.view_name and len(self.view_name) > 190:
self.view_name = self._shorten(self.view_name)

super(Request, self).save(*args, **kwargs)
Request.garbage_collect(force=False)

Expand Down

0 comments on commit c7d7aee

Please sign in to comment.