Log message for revision 80941: Launchpad #143902: Fixed App.ImageFile to use a stream iterator to output the file. Avoid loading the file content when guessing the mimetype and only load the first 1024 bytes of the file when it cannot be guessed from the filename.
Changed: U Zope/trunk/doc/CHANGES.txt U Zope/trunk/lib/python/App/ImageFile.py -=- Modified: Zope/trunk/doc/CHANGES.txt =================================================================== --- Zope/trunk/doc/CHANGES.txt 2007-10-20 09:57:58 UTC (rev 80940) +++ Zope/trunk/doc/CHANGES.txt 2007-10-20 10:31:27 UTC (rev 80941) @@ -175,6 +175,11 @@ Bugs Fixed + - Launchpad #143902: Fixed App.ImageFile to use a stream iterator to + output the file. Avoid loading the file content when guessing the + mimetype and only load the first 1024 bytes of the file when it cannot + be guessed from the filename. + - Changed PageTemplateFile not to load the file contents on Zope startup anymore but on first access instead. This brings them inline with the zope.pagetemplate version and speeds up Zope startup. Modified: Zope/trunk/lib/python/App/ImageFile.py =================================================================== --- Zope/trunk/lib/python/App/ImageFile.py 2007-10-20 09:57:58 UTC (rev 80940) +++ Zope/trunk/lib/python/App/ImageFile.py 2007-10-20 10:31:27 UTC (rev 80941) @@ -15,6 +15,7 @@ __version__='$Revision: 1.20 $'[11:-2] import os +import stat import time import Acquisition @@ -28,6 +29,8 @@ from zope.contenttype import guess_content_type +from ZPublisher.Iterators import filestream_iterator + class ImageFile(Acquisition.Explicit): """Image objects stored in external files.""" @@ -48,16 +51,28 @@ max_age = 3600 # One hour self.cch = 'public,max-age=%d' % max_age - data = open(path, 'rb').read() - content_type, enc=guess_content_type(path, data) + # First try to get the content_type by name + content_type, enc=guess_content_type(path, default='failed') + + if content_type == 'failed': + # This failed, lets look into the file content + img = open(path, 'rb') + data = img.read(1024) # 1k should be enough + img.close() + + content_type, enc=guess_content_type(path, data) + if content_type: self.content_type=content_type else: - self.content_type='image/%s' % path[path.rfind('.')+1:] - self.__name__=path[path.rfind('/')+1:] - self.lmt=float(os.stat(path)[8]) or time.time() - self.lmh=rfc1123_date(self.lmt) + ext = os.path.splitext(path)[-1].replace('.', '') + self.content_type='image/%s' % ext + self.__name__ = os.path.split(path)[-1] + stat_info = os.stat(path) + self.size = stat_info[stat.ST_SIZE] + self.lmt = float(stat_info[stat.ST_MTIME]) or time.time() + self.lmh = rfc1123_date(self.lmt) def index_html(self, REQUEST, RESPONSE): """Default document""" @@ -67,7 +82,8 @@ RESPONSE.setHeader('Content-Type', self.content_type) RESPONSE.setHeader('Last-Modified', self.lmh) RESPONSE.setHeader('Cache-Control', self.cch) - header=REQUEST.get_header('If-Modified-Since', None) + RESPONSE.setHeader('Content-Length', str(self.size).replace('L', '')) + header = REQUEST.get_header('If-Modified-Since', None) if header is not None: header=header.split(';')[0] # Some proxies seem to send invalid date strings for this @@ -87,7 +103,7 @@ RESPONSE.setStatus(304) return '' - return open(self.path,'rb').read() + return filestream_iterator(self.path, mode='rb') security.declarePublic('HEAD') def HEAD(self, REQUEST, RESPONSE): _______________________________________________ Zope-Checkins maillist - Zope-Checkins@zope.org http://mail.zope.org/mailman/listinfo/zope-checkins