Commit 36ca4b8e by Rowan Seymour Committed by Tom Christie

Make offset_cutoff a class attribute in CursorPagination so that it can be…

Make offset_cutoff a class attribute in CursorPagination so that it can be easily overridden in subclasses (#4212)
parent 879652ec
...@@ -407,7 +407,7 @@ class LimitOffsetPagination(BasePagination): ...@@ -407,7 +407,7 @@ class LimitOffsetPagination(BasePagination):
class CursorPagination(BasePagination): class CursorPagination(BasePagination):
""" """
The cursor pagination implementation is neccessarily complex. The cursor pagination implementation is necessarily complex.
For an overview of the position/offset style we use, see this post: For an overview of the position/offset style we use, see this post:
http://cramer.io/2011/03/08/building-cursors-for-the-disqus-api http://cramer.io/2011/03/08/building-cursors-for-the-disqus-api
""" """
...@@ -417,6 +417,12 @@ class CursorPagination(BasePagination): ...@@ -417,6 +417,12 @@ class CursorPagination(BasePagination):
ordering = '-created' ordering = '-created'
template = 'rest_framework/pagination/previous_and_next.html' template = 'rest_framework/pagination/previous_and_next.html'
# The offset in the cursor is used in situations where we have a
# nearly-unique index. (Eg millisecond precision creation timestamps)
# We guard against malicious users attempting to cause expensive database
# queries, by having a hard cap on the maximum possible size of the offset.
offset_cutoff = 1000
def paginate_queryset(self, queryset, request, view=None): def paginate_queryset(self, queryset, request, view=None):
self.page_size = self.get_page_size(request) self.page_size = self.get_page_size(request)
if not self.page_size: if not self.page_size:
...@@ -647,18 +653,12 @@ class CursorPagination(BasePagination): ...@@ -647,18 +653,12 @@ class CursorPagination(BasePagination):
if encoded is None: if encoded is None:
return None return None
# The offset in the cursor is used in situations where we have a
# nearly-unique index. (Eg millisecond precision creation timestamps)
# We guard against malicious users attempting to cause expensive database
# queries, by having a hard cap on the maximum possible size of the offset.
OFFSET_CUTOFF = 1000
try: try:
querystring = b64decode(encoded.encode('ascii')).decode('ascii') querystring = b64decode(encoded.encode('ascii')).decode('ascii')
tokens = urlparse.parse_qs(querystring, keep_blank_values=True) tokens = urlparse.parse_qs(querystring, keep_blank_values=True)
offset = tokens.get('o', ['0'])[0] offset = tokens.get('o', ['0'])[0]
offset = _positive_int(offset, cutoff=OFFSET_CUTOFF) offset = _positive_int(offset, cutoff=self.offset_cutoff)
reverse = tokens.get('r', ['0'])[0] reverse = tokens.get('r', ['0'])[0]
reverse = bool(int(reverse)) reverse = bool(int(reverse))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment