HttpResponse._get_content is broken for iterables (HttpResponse._is_string = False)
|Reported by:||Eloff||Owned by:||nobody|
|Has patch:||yes||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
Passing an iterable to HttpResponse(), the iterable gets iterated over and joined once for EVERY call to _get_content. Quite a bit of middleware, including django's own Common middleware, accesses response.content, so this gotcha hits just about everyone who passes an iterator to HttpResponse.
The attached patch simply converts the iterable to a string and caches it on the first call to _get_content (by converting the response from an iterable response to a string response.) If you go to all the trouble to convert the iterable to a string, there's no point doing it again and again.
However, if you want to do any streaming, you must set USE_ETAGS = False in your settings, and avoid any 3rd party middleware that acceses response.content. That is you can have streaming, or you can have etags, but not both unless you do your own etags. Not a big deal, but gets to be really annoying if you have more middleware doing stuff with .content. There should really be a way mark an HttpResponse as DO NOT CALL .content UNDER PAIN OF DEATH... (and make _get_content raise an exception in this case) but I leave that as a problem for someone else.