Monday, March 19, 2007

Sendfile Patch for Zope2

I've put together a patch for Zope that allows code to use the sendfile system call to transfer data out of Zope.

As this requires a file object, it's only available for use from trusted code, so that means inside a Product or an External method.

The good news is, that it's fairly easy to write an External method that does something useful like serve contents from a directory.

Here's an example external method that serves files from '/shared/images'

import os
directory = '/shared/images'

def Image(self, filename):
newPath = os.path.join(directory, filename)
if not os.access(newPath, os.F_OK|os.R_OK):
self.REQUEST.RESPONSE.setStatus(404)
return ''
f = open(newPath, 'rb')
self.REQUEST.RESPONSE.sendfile(f, content_type='image/jpeg', other_headers = {'Content-Disposition', 'inline;filename=%s'%(filename))
f.close()
return ''

It uses the sendfile wrapper module from here.

It gives you a speed up of 2-3 times serving content out of Zope from the filesystem.
I also have a patch for ExternalFile to let this use the sendfile patch.

You can get the code and the patch from zope.org