Description

This patch is intended to improve the behavior of the django.middleware.http.ConditionalGetMiddleware? middleware. When a particular django view has at least two decorators that work with redirecting behavior, Firefox will send a ETag that seems to be valid since the response is nothing more than a Location redirect, thus the content-length is 0 and the ETag is valid for the two steps created by the two decorators that redirect the user to different pages (Example decorator : @login_required and another that acts very similarly). The bug is that the browser will receive a Not Modified header once the users passes the first decorator when he gets redirected by to the original view.

The FIX: The fix changes the behavior of the django.middleware.http.ConditionalGetMiddleware? to not send a 304 response code if the content-length is 0 or undefined.

I'm not sure if it's proper, but it seems good of a fix and it actually fixes my issue. So, I just wanted to shared it, hopefully it can make it in the code-base.

This fix will require a little bit of documentation change to explain the extra condition.

Change History (15)

I don't deny that this fixes the problem you describe, but it feels like there is something else going on. Firefox should only be sending an etag if the server provided one. Before I start making exceptions in ConditionalGetMiddleware, I'd like to rule out the possiblity that the ETags are getting set incorrectly in the first place.

Can you provide a specific test case where this happens i.e., an example view, decorated in a way that exhibits the problem? You should also provide your Firefox version, in case it is version dependent.

The problem is that patch_response_headers sets an ETag header regardless of the response status_code. This differs from the behavior implemented by CommonMiddleware, which only sets ETags when 200 <= response.status_code < 300. Making it consistent with CommonMiddleware behavior fixes things for me.