[Zope-Checkins] CVS: Zope/lib/python/ZServer -
FTPResponse.py:1.13.8.1 FTPServer.py:1.26.8.4
HTTPResponse.py:1.43.8.2 Producers.py:1.9.8.1
Chris McDonough
chrism at plope.com
Sun Mar 28 06:12:19 EST 2004
Update of /cvs-repository/Zope/lib/python/ZServer
In directory cvs.zope.org:/tmp/cvs-serv2971/lib/python/ZServer
Modified Files:
Tag: Zope-2_7-branch
FTPResponse.py FTPServer.py HTTPResponse.py Producers.py
Log Message:
Merge chrism-publishfile-branch. See http://dev.zope.org/Wikis/DevSite/Proposals/FasterStaticContentServing for more information.
=== Zope/lib/python/ZServer/FTPResponse.py 1.13 => 1.13.8.1 ===
--- Zope/lib/python/ZServer/FTPResponse.py:1.13 Tue Mar 18 16:15:14 2003
+++ Zope/lib/python/ZServer/FTPResponse.py Sun Mar 28 06:11:48 2004
@@ -26,9 +26,6 @@
"""
def __str__(self):
-# return ZServerHTTPResponse.__str__(self)
- # ZServerHTTPResponse.__str__(self) return HTTP headers
- # Why should be send them to the FTP client ??? (ajung)
return ''
def outputBody(self):
=== Zope/lib/python/ZServer/FTPServer.py 1.26.8.3 => 1.26.8.4 ===
--- Zope/lib/python/ZServer/FTPServer.py:1.26.8.3 Wed Dec 17 16:00:43 2003
+++ Zope/lib/python/ZServer/FTPServer.py Sun Mar 28 06:11:48 2004
@@ -168,8 +168,10 @@
self.listdir(dir, long)
def listdir (self, path, long=0):
- response=make_response(self, self.listdir_completion, long)
- request=FTPRequest(path, 'LST', self, response,globbing=self.globbing,recursive=self.recursive)
+ response = make_response(self, self.listdir_completion, long)
+ request = FTPRequest(path, 'LST', self, response,
+ globbing=self.globbing,
+ recursive=self.recursive)
handle(self.module, request, response)
def listdir_completion(self, long, response):
@@ -308,7 +310,19 @@
if status==200:
self.make_xmit_channel()
if not response._wrote:
- self.client_dc.push(response.body)
+ # chrism: we explicitly use a large-buffered producer here to
+ # increase speed. Using "client_dc.push" with the body causes
+ # a simple producer with a buffer size of 512 to be created
+ # to serve the data, and it's very slow
+ # (about 100 times slower than the large-buffered producer)
+ self.client_dc.push_with_producer(
+ asynchat.simple_producer(response.body, 1<<16))
+ # chrism: if the response has a bodyproducer, it means that
+ # the actual body was likely an empty string. This happens
+ # typically when someone returns a StreamIterator from
+ # Zope application code.
+ if response._bodyproducer:
+ self.client_dc.push_with_producer(response._bodyproducer)
else:
for producer in self._response_producers:
self.client_dc.push_with_producer(producer)
@@ -645,3 +659,4 @@
# override asyncore limits for nt's listen queue size
self.accepting = 1
return self.socket.listen (num)
+
=== Zope/lib/python/ZServer/HTTPResponse.py 1.43.8.1 => 1.43.8.2 ===
--- Zope/lib/python/ZServer/HTTPResponse.py:1.43.8.1 Thu Jan 8 18:34:02 2004
+++ Zope/lib/python/ZServer/HTTPResponse.py Sun Mar 28 06:11:48 2004
@@ -21,13 +21,14 @@
from cStringIO import StringIO
import thread
from ZPublisher.HTTPResponse import HTTPResponse
+from ZPublisher.Iterators import IStreamIterator
from medusa.http_date import build_http_date
from PubCore.ZEvent import Wakeup
from medusa.producers import hooked_producer
from medusa import http_server
import asyncore
from Producers import ShutdownProducer, LoggingProducer, CallbackProducer, \
- file_part_producer, file_close_producer
+ file_part_producer, file_close_producer, iterator_producer
from types import LongType
import DebugLogger
@@ -49,6 +50,7 @@
_streaming=0
# using chunking transfer-encoding
_chunking=0
+ _bodyproducer = None
def __str__(self,
html_search=re.compile('<html>',re.I).search,
@@ -230,6 +232,22 @@
self._retried_response = response
return response
+ def outputBody(self):
+ """Output the response body"""
+ self.stdout.write(str(self))
+ if self._bodyproducer:
+ self.stdout.write(self._bodyproducer, 0)
+
+ def setBody(self, body, title='', is_error=0, **kw):
+ """ Accept either a stream iterator or a string as the body """
+ if IStreamIterator.isImplementedBy(body):
+ assert(self.headers.has_key('content-length'))
+ # wrap the iterator up in a producer that medusa can understand
+ self._bodyproducer = iterator_producer(body)
+ HTTPResponse.setBody(self, '', title, is_error, **kw)
+ return self
+ else:
+ HTTPResponse.setBody(self, body, title, is_error, **kw)
class ChannelPipe:
"""Experimental pipe from ZPublisher to a ZServer Channel.
=== Zope/lib/python/ZServer/Producers.py 1.9 => 1.9.8.1 ===
--- Zope/lib/python/ZServer/Producers.py:1.9 Tue Mar 18 16:15:14 2003
+++ Zope/lib/python/ZServer/Producers.py Sun Mar 28 06:11:48 2004
@@ -19,14 +19,12 @@
class ShutdownProducer:
"shuts down medusa"
-
def more(self):
asyncore.close_all()
class LoggingProducer:
"logs request"
-
def __init__(self, logger, bytes, method='log'):
self.logger=logger
self.bytes=bytes
@@ -40,7 +38,6 @@
class CallbackProducer:
"Performs a callback in the channel's thread"
-
def __init__(self, callback):
self.callback=callback
@@ -52,7 +49,6 @@
class file_part_producer:
"producer wrapper for part of a file[-like] objects"
-
# match http_channel's outgoing buffer size
out_buffer_size = 1<<16
@@ -91,7 +87,6 @@
return data
-
class file_close_producer:
def __init__(self, file):
self.file=file
@@ -102,3 +97,13 @@
file.close()
self.file=None
return ''
+
+class iterator_producer:
+ def __init__(self, iterator):
+ self.iterator = iterator
+
+ def more(self):
+ try:
+ return self.iterator.next()
+ except StopIteration:
+ return ''
More information about the Zope-Checkins
mailing list