(request, etag=None, last_modified=None, response=None)
| 162 | |
| 163 | |
| 164 | def get_conditional_response(request, etag=None, last_modified=None, response=None): |
| 165 | # Only return conditional responses on successful requests. |
| 166 | if response and not (200 <= response.status_code < 300): |
| 167 | return response |
| 168 | |
| 169 | # Get HTTP request headers. |
| 170 | if_match_etags = parse_etags(request.META.get("HTTP_IF_MATCH", "")) |
| 171 | if_unmodified_since = request.META.get("HTTP_IF_UNMODIFIED_SINCE") |
| 172 | if_unmodified_since = if_unmodified_since and parse_http_date_safe( |
| 173 | if_unmodified_since |
| 174 | ) |
| 175 | if_none_match_etags = parse_etags(request.META.get("HTTP_IF_NONE_MATCH", "")) |
| 176 | if_modified_since = request.META.get("HTTP_IF_MODIFIED_SINCE") |
| 177 | if_modified_since = if_modified_since and parse_http_date_safe(if_modified_since) |
| 178 | |
| 179 | # Evaluation of request preconditions below follows RFC 9110 Section |
| 180 | # 13.2.2. |
| 181 | # Step 1: Test the If-Match precondition. |
| 182 | if if_match_etags and not _if_match_passes(etag, if_match_etags): |
| 183 | return _precondition_failed(request) |
| 184 | |
| 185 | # Step 2: Test the If-Unmodified-Since precondition. |
| 186 | if ( |
| 187 | not if_match_etags |
| 188 | and if_unmodified_since |
| 189 | and not _if_unmodified_since_passes(last_modified, if_unmodified_since) |
| 190 | ): |
| 191 | return _precondition_failed(request) |
| 192 | |
| 193 | # Step 3: Test the If-None-Match precondition. |
| 194 | if if_none_match_etags and not _if_none_match_passes(etag, if_none_match_etags): |
| 195 | if request.method in ("GET", "HEAD"): |
| 196 | return _not_modified(request, response) |
| 197 | else: |
| 198 | return _precondition_failed(request) |
| 199 | |
| 200 | # Step 4: Test the If-Modified-Since precondition. |
| 201 | if ( |
| 202 | not if_none_match_etags |
| 203 | and if_modified_since |
| 204 | and not _if_modified_since_passes(last_modified, if_modified_since) |
| 205 | and request.method in ("GET", "HEAD") |
| 206 | ): |
| 207 | return _not_modified(request, response) |
| 208 | |
| 209 | # Step 5: Test the If-Range precondition (not supported). |
| 210 | # Step 6: Return original response since there isn't a conditional |
| 211 | # response. |
| 212 | return response |
| 213 | |
| 214 | |
| 215 | def _if_match_passes(target_etag, etags): |
no test coverage detected