Commit cbcaebbc authored by Hanno Schlichting's avatar Hanno Schlichting

Launchpad #143902: Fixed App.ImageFile to use a stream iterator to output the...

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.
parent ceaa8f63
......@@ -175,6 +175,11 @@ Zope Changes
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.
......
......@@ -15,6 +15,7 @@
__version__='$Revision: 1.20 $'[11:-2]
import os
import stat
import time
import Acquisition
......@@ -28,6 +29,8 @@ from DateTime import DateTime
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 @@ class ImageFile(Acquisition.Explicit):
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 @@ class ImageFile(Acquisition.Explicit):
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 @@ class ImageFile(Acquisition.Explicit):
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):
......
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