Commit 59859036 authored by Jens Vagelpohl's avatar Jens Vagelpohl

- forward-port DTMLMethod/filestream_iterator fix from 2.7

parent 9344f756
...@@ -51,6 +51,9 @@ Zope Changes ...@@ -51,6 +51,9 @@ Zope Changes
Bugs fixed Bugs fixed
- DTML Methods were not interoperable with the new filestream_iterator
and caches based on it (FileCacheManager).
- Collector #1655: fixed severe memory leak in TemporaryStorage - Collector #1655: fixed severe memory leak in TemporaryStorage
- Collector #1407: fixed XML escaping problem introduced in 2.7.4 b1 - Collector #1407: fixed XML escaping problem introduced in 2.7.4 b1
......
...@@ -32,6 +32,7 @@ from AccessControl.DTML import RestrictedDTML ...@@ -32,6 +32,7 @@ from AccessControl.DTML import RestrictedDTML
from Cache import Cacheable from Cache import Cacheable
from zExceptions import Forbidden from zExceptions import Forbidden
from zExceptions.TracebackSupplement import PathTracebackSupplement from zExceptions.TracebackSupplement import PathTracebackSupplement
from ZPublisher.Iterators import IStreamIterator
_marker = [] # Create a new marker object. _marker = [] # Create a new marker object.
...@@ -102,6 +103,19 @@ class DTMLMethod(RestrictedDTML, HTML, Acquisition.Implicit, RoleManager, ...@@ -102,6 +103,19 @@ class DTMLMethod(RestrictedDTML, HTML, Acquisition.Implicit, RoleManager,
if not self._cache_namespace_keys: if not self._cache_namespace_keys:
data = self.ZCacheable_get(default=_marker) data = self.ZCacheable_get(default=_marker)
if data is not _marker: if data is not _marker:
if ( IStreamIterator.isImplementedBy(data) and
RESPONSE is not None ):
# This is a stream iterator and we need to set some
# headers now before giving it to medusa
if RESPONSE.headers.get('content-length', None) is None:
RESPONSE.setHeader('content-length', len(data))
if ( RESPONSE.headers.get('content-type', None) is None and
RESPONSE.headers.get('Content-type', None) is None ):
ct = ( self.__dict__.get('content_type') or
self.default_content_type )
RESPONSE.setHeader('content-type', ct)
# Return cached results. # Return cached results.
return data return data
......
...@@ -20,6 +20,13 @@ class IStreamIterator(Interface): ...@@ -20,6 +20,13 @@ class IStreamIterator(Interface):
StopIeration if we've reached the end of the bytestream. StopIeration if we've reached the end of the bytestream.
""" """
def __len__(self):
"""
Return an integer representing the length of the object
in bytes.
"""
class filestream_iterator(file): class filestream_iterator(file):
""" """
a file subclass which implements an iterator that returns a a file subclass which implements an iterator that returns a
...@@ -37,5 +44,11 @@ class filestream_iterator(file): ...@@ -37,5 +44,11 @@ class filestream_iterator(file):
if not data: if not data:
raise StopIteration raise StopIteration
return data return data
def __len__(self):
cur_pos = self.tell()
self.seek(0, 2)
size = self.tell()
self.seek(cur_pos, 0)
return size
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment