Commit 033fdbb8 authored by Gerhard Weis's avatar Gerhard Weis

Introduce IUnboundStreamIterator to support publishing iterators of unknown length

parent 91f54a4e
from zope.interface import Interface
from zope.interface import implements
class IUnboundStreamIterator(Interface):
"""
An iterator with unknown length that can be published.
"""
def next():
"""
Return a sequence of bytes out of the bytestream, or raise
StopIeration if we've reached the end of the bytestream.
"""
class IStreamIterator(Interface):
"""
An iterator that can be published.
An iterator with known length that can be published.
IStreamIterators must not read from the object database.
After the application finishes interpreting a request and
......@@ -15,12 +27,6 @@ class IStreamIterator(Interface):
but it has a chance of going insane if it happens to be loading
or storing something in the other thread at the same time. """
def next():
"""
Return a sequence of bytes out of the bytestream, or raise
StopIeration if we've reached the end of the bytestream.
"""
def __len__():
"""
Return an integer representing the length of the object
......
......@@ -32,7 +32,7 @@ from ZPublisher.Publish import dont_publish_class
from ZPublisher.Publish import get_module_info
from ZPublisher.Publish import missing_name
from ZPublisher.pubevents import PubStart, PubBeforeCommit, PubAfterTraversal
from ZPublisher.Iterators import IStreamIterator
from ZPublisher.Iterators import IUnboundStreamIterator, IStreamIterator
_NOW = None # overwrite for testing
def _now():
......@@ -137,10 +137,13 @@ class WSGIResponse(HTTPResponse):
body.seek(0)
self.setHeader('Content-Length', '%d' % length)
self.body = body
elif IStreamIterator.providedBy(body):
elif IUnboundStreamIterator.providedBy(body):
self.body = body
self._streaming = 1
HTTPResponse.setBody(self, '', title, is_error)
elif IStreamIterator.providedBy(body):
self.body = body
HTTPResponse.setBody(self, '', title, is_error)
else:
HTTPResponse.setBody(self, body, title, is_error)
......
......@@ -136,6 +136,28 @@ class WSGIResponseTests(unittest.TestCase):
time.gmtime(time.mktime(WHEN)))
self.assertTrue(('Date', whenstr) in headers)
def test_setBody_IUnboundStreamIterator(self):
from ZPublisher.Iterators import IUnboundStreamIterator
from zope.interface import implements
class test_streamiterator:
implements(IUnboundStreamIterator)
data = "hello"
done = 0
def next(self):
if not self.done:
self.done = 1
return self.data
raise StopIteration
response = self._makeOne()
response.setStatus(200)
body = test_streamiterator()
response.setBody(body)
response.finalize()
self.assertTrue(body is response.body)
def test_setBody_IStreamIterator(self):
from ZPublisher.Iterators import IStreamIterator
from zope.interface import implements
......@@ -151,6 +173,9 @@ class WSGIResponseTests(unittest.TestCase):
return self.data
raise StopIteration
def __len__(self):
return len(self.data)
response = self._makeOne()
response.setStatus(200)
body = test_streamiterator()
......
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