#20187: Django 1.5 using a cached HttpResponse with WSGI has an empty body
-------------------------------+--------------------------
     Reporter:  smbrooks1@…    |      Owner:  nobody
         Type:  Bug            |     Status:  new
    Component:  HTTP handling  |    Version:  1.5
     Severity:  Normal         |   Keywords:  HttpResponse
 Triage Stage:  Unreviewed     |  Has patch:  0
Easy pickings:  0              |      UI/UX:  0
-------------------------------+--------------------------
 With the change to HttpResponse made in Django 1.5, I'm finding that in my
 code, which caches a generated response, results in an empty body when
 that page is requested a second time. The first time the page is
 requested, it is not in the cache, and the page is generated normally and
 added to the cache. A subsequent request for the same page finds the
 response in the cache and that response is returned, but with a content
 length of zero.

 The reason is that the HttpResponse in Django 1.5 does not reset the
 content iterator when the content is requested to be iterated over again
 (the next time the response content is required).

 I note the comments made about the way an iterator should behave when
 requested to iterate again:
 [https://code.djangoproject.com/ticket/13222]
 and the code which was added to explicitly prevent a reiteration from
 resetting the iterator. However, that causes a problem when using cached
 responses.

 The HttpResponse in my case was not created by passing an iterator to
 HttpResponse. It is just using a string.

 The problem is that the `__iter__` method of HttpResponse contains the
 line:

 {{{
     if not hasattr(self, '_iterator'):
       self._iterator = iter(self._container)
 }}}


 This prevents the iterator being reset the next time it is required to
 iterate over the content.
 _container still has the original content, but `__iter__` does not reset
 the iterator as _iterator exists as an attribute since the first time that
 response was returned. The cached response is returning a used iterator,
 which returns no content.

 I suspect this is a bug.
 What about a work-around in the meantime?
 When I retrieve the response from the cache, I could do:

 {{{
 response._iterator = iter(response._container)
 }}}


 or:

 {{{
 del response._iterator
 }}}


 This works, but makes my code dependent on the internals of the
 HttpResponse class, which isn't great.

 My suggestion is to change the `__iter__` method for HttpResponse such
 that it creates an instance of a separate iterator class. The `__iter__`
 method should not return self. It would be OK for the `__iter__` method of
 the separate iterator class to return self. This should avoid the problem
 reported in [https://code.djangoproject.com/ticket/13222].

 I accept that StreamingHttpResponse instances can only be iterated once,
 and are therefore not suitable for caching.

 Kind regards,
 Steve

-- 
Ticket URL: <https://code.djangoproject.com/ticket/20187>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to