88from rest_framework import status
99from rest_framework .permissions import SAFE_METHODS
1010from rest_framework .response import Response
11- from rest_framework_extensions .exceptions import PreconditionRequiredException
1211
1312from rest_framework_extensions .utils import prepare_header_name
1413from rest_framework_extensions .settings import extensions_api_settings
@@ -30,7 +29,7 @@ def __call__(self, func):
3029 this = self
3130
3231 @wraps (func , assigned = available_attrs (func ))
33- def inner (self , request , * args , ** kwargs ):
32+ def wrapper (self , request , * args , ** kwargs ):
3433 return this .process_conditional_request (
3534 view_instance = self ,
3635 view_method = func ,
@@ -39,7 +38,7 @@ def inner(self, request, *args, **kwargs):
3938 kwargs = kwargs ,
4039 )
4140
42- return inner
41+ return wrapper
4342
4443 def process_conditional_request (self ,
4544 view_instance ,
@@ -136,68 +135,21 @@ def _get_and_log_precondition_failed_response(self, request):
136135 )
137136 return Response (status = status .HTTP_412_PRECONDITION_FAILED )
138137
139-
140- class APIETAGProcessor (ETAGProcessor ):
141- """
142- This class is responsible for calculating the ETag value given (a list of) model instance(s).
143-
144- It does not make sense to compute a default ETag here, because the processor would always issue a 304 response,
145- even if the response was modified meanwhile.
146- Therefore the `APIETAGProcessor` cannot be used without specifying an `etag_func` as keyword argument.
147-
148- According to RFC 6585, conditional headers may be enforced for certain services that support conditional
149- requests. For optimistic locking, the server should respond status code 428 including a description on how
150- to resubmit the request successfully, see https://tools.ietf.org/html/rfc6585#section-3.
151- """
152-
153- # require a pre-conditional header (e.g. If-Match) for unsafe HTTP methods (RFC 6585)
154- # override this defaults, if required
155- precondition_map = {'PUT' : ['If-Match' ],
156- 'PATCH' : ['If-Match' ],
157- 'DELETE' : ['If-Match' ]}
158-
159- def __init__ (self , etag_func = None , rebuild_after_method_evaluation = False , precondition_map = None ):
160- assert etag_func is not None , ('None-type functions are not allowed for processing API ETags.'
161- 'You must specify a proper function to calculate the API ETags '
162- 'using the "etag_func" keyword argument.' )
163-
164- if precondition_map is not None :
165- self .precondition_map = precondition_map
166- assert isinstance (self .precondition_map , dict ), ('`precondition_map` must be a dict, where '
167- 'the key is the HTTP verb, and the value is a list of '
168- 'HTTP headers that must all be present for that request.' )
169-
170- super (APIETAGProcessor , self ).__init__ (etag_func = etag_func ,
171- rebuild_after_method_evaluation = rebuild_after_method_evaluation )
172-
173- def get_etags_and_matchers (self , request ):
174- """Get the etags from the header and perform a validation against the required preconditions."""
175- # evaluate the preconditions, raises 428 if condition is not met
176- self .evaluate_preconditions (request )
177- # alright, headers are present, extract the values and match the conditions
178- return super (APIETAGProcessor , self ).get_etags_and_matchers (request )
179-
180- def evaluate_preconditions (self , request ):
181- """Evaluate whether the precondition for the request is met."""
182- if request .method .upper () in self .precondition_map .keys ():
183- required_headers = self .precondition_map .get (request .method .upper (), [])
184- # check the required headers
185- for header in required_headers :
186- if not request .META .get (prepare_header_name (header )):
187- # raise an error for each header that does not match
188- logger .warning ('Precondition required: %s' , request .path ,
189- extra = {
190- 'status_code' : status .HTTP_428_PRECONDITION_REQUIRED ,
191- 'request' : request
192- }
193- )
194- # raise an RFC 6585 compliant exception
195- raise PreconditionRequiredException (detail = 'Precondition required. This "%s" request '
196- 'is required to be conditional. '
197- 'Try again using "%s".' % (request .method , header )
198- )
199- return True
200-
138+ #
139+ # class APIETAGProcessor(ETAGProcessor):
140+ # """
141+ # This class is responsible for calculating the ETag value given (a list of) model instance(s).
142+ #
143+ # It does not make sense to compute a default ETag here, because the processor would always issue a 304 response,
144+ # even if the response was modified meanwhile.
145+ # Therefore the `APIETAGProcessor` cannot be used without specifying an `etag_func` as keyword argument.
146+ # """
147+ # def __init__(self, etag_func=None, rebuild_after_method_evaluation=False):
148+ # assert etag_func is not None, ('None-type functions are not allowed for processing API ETags.'
149+ # 'You must specify a proper function to calculate the API ETags '
150+ # 'using the "etag_func" keyword argument.')
151+ #
152+ # super(APIETAGProcessor, self).__init__(etag_func=etag_func,
153+ # rebuild_after_method_evaluation=rebuild_after_method_evaluation)
201154
202155etag = ETAGProcessor
203- api_etag = APIETAGProcessor
0 commit comments