我目前正在尝试配置 collect.xsendfile、Apache mod_xsendfile 和 Plone 4。

显然 Apache 进程在文件系统上看不到 blobstrage 文件,因为它们包含权限:

ls -lh var/blobstorage/0x00/0x00/0x00/0x00/0x00/0x18/0xd5/0x19/0x038ea09d0eddc611.blob
-r-------- 1 plone plone 1006K 5 月 28 日 15:30 var/blobstorage/0x00/0x00/0x00/0x00/0x00/0x18/0xd5/0x19/0x038ea09d0eddc611.blob

如何配置 blobstorage 以授予其他权限,以便 Apache 可以访问这些文件?

最佳答案

blobstorage 写入其目录和文件的模式在 ZODB.blob 中硬编码。具体来说,标准的 ZODB.blob.FileSystemHelper 类默认创建安全目录(仅对当前用户可读和可写)。

您可以提供自己的 FileSystemHelper 实现,这可以使其可配置,或者只是将目录模式设置为 0750 ,然后修补 ZODB.blob.BlobStorageMixin 以使用您的类而不是默认值:

import os
from ZODB import utils
from ZODB.blob import FilesystemHelper, BlobStorageMixin
from ZODB.blob import log, LAYOUT_MARKER

class GroupReadableFilesystemHelper(FilesystemHelper):
    def create(self):
        if not os.path.exists(self.base_dir):
            os.makedirs(self.base_dir, 0750)
            log("Blob directory '%s' does not exist. "
                "Created new directory." % self.base_dir)
        if not os.path.exists(self.temp_dir):
            os.makedirs(self.temp_dir, 0750)
            log("Blob temporary directory '%s' does not exist. "
                "Created new directory." % self.temp_dir)

        if not os.path.exists(os.path.join(self.base_dir, LAYOUT_MARKER)):
            layout_marker = open(
                os.path.join(self.base_dir, LAYOUT_MARKER), 'wb')
            layout_marker.write(self.layout_name)
        else:
            layout = open(os.path.join(self.base_dir, LAYOUT_MARKER), 'rb'
                          ).read().strip()
            if layout != self.layout_name:
                raise ValueError(
                    "Directory layout `%s` selected for blob directory %s, but "
                    "marker found for layout `%s`" %
                    (self.layout_name, self.base_dir, layout))

    def isSecure(self, path):
        """Ensure that (POSIX) path mode bits are 0750."""
        return (os.stat(path).st_mode & 027) == 0

    def getPathForOID(self, oid, create=False):
        """Given an OID, return the path on the filesystem where
        the blob data relating to that OID is stored.

        If the create flag is given, the path is also created if it didn't
        exist already.

        """
        # OIDs are numbers and sometimes passed around as integers. For our
        # computations we rely on the 64-bit packed string representation.
        if isinstance(oid, int):
            oid = utils.p64(oid)

        path = self.layout.oid_to_path(oid)
        path = os.path.join(self.base_dir, path)

        if create and not os.path.exists(path):
            try:
                os.makedirs(path, 0750)
            except OSError:
                # We might have lost a race.  If so, the directory
                # must exist now
                assert os.path.exists(path)
        return path


def _blob_init_groupread(self, blob_dir, layout='automatic'):
    self.fshelper = GroupReadableFilesystemHelper(blob_dir, layout)
    self.fshelper.create()
    self.fshelper.checkSecure()
    self.dirty_oids = []

BlobStorageMixin._blob_init = _blob_init_groupread

相当全面,您可能希望将此作为 ZODB3 的功能请求 :-)

关于blob - collect.xsendfile、ZODB blob 和 UNIX 文件权限,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6168566/

10-12 13:44