I'm trying to implement conditional caching using django.middleware.http.CondtionalGetMiddleware. I'm able to correctly return 304/200 if I provide an If-None-Match with ETag value in the request headers.

However, I'm unable to do so when I provide If-Modified-Since in the request headers. I believe it is because my response does not contain a header called Last-Modified, which ConditionalGetMiddleware seems to be requiring, as follows:

class ConditionalGetMiddleware(MiddlewareMixin):
    """
    Handle conditional GET operations. If the response has an ETag or
    Last-Modified header and the request has If-None-Match or If-Modified-Since,
    replace the response with HttpNotModified. Add an ETag header if needed.
    """

    def process_response(self, request, response):
        # It's too late to prevent an unsafe request with a 412 response, and
        # for a HEAD request, the response body is always empty so computing
        # an accurate ETag isn't possible.
        if request.method != "GET":
            return response

        if self.needs_etag(response) and not response.has_header("ETag"):
            set_response_etag(response)

        etag = response.get("ETag")
        last_modified = response.get("Last-Modified")
        last_modified = last_modified and parse_http_date_safe(last_modified)

        if etag or last_modified:
            return get_conditional_response(
                request,
                etag=etag,
                last_modified=last_modified,
                response=response,
            )

        return response

    def needs_etag(self, response):
        """Return True if an ETag header should be added to response."""
        ...

Ideally, I would like Last-Modified to have a value similar to ConcernedModel.objects.latest("updated_at").

One way that comes to mind is to send Last-Modified in every API response.

Looking for better ideas/any shortcuts, please?

0

There are 0 best solutions below