我一直在试图作出"最佳做法"方法来管理文件上载有Turbogears2和迄今没有真正发现的任何例子。我已经想出了一个办法实际上载的文件,但我不知道该如何可靠它我们。

此外,这将是一个很好的方式来获得上载的文件的名字吗?

    file = request.POST['file']
    permanent_file = open(os.path.join(asset_dirname,
        file.filename.lstrip(os.sep)), 'w')
    shutil.copyfileobj(file.file, permanent_file)
    file.file.close()
    this_file = self.request.params["file"].filename 
    permanent_file.close()

因此,假如我的理解正确的话,会像这样的东西避免核心'名'的问题?id=usb驱.

    file = request.POST['file']
    permanent_file = open(os.path.join(asset_dirname,
        id.lstrip(os.sep)), 'w')
    shutil.copyfileobj(file.file, permanent_file)
    file.file.close()
    this_file = file.filename
    permanent_file.close()
有帮助吗?

解决方案

@mhawke - 你是对的,你必须处理 - 取决于你所使用的文件做什么,如果没有问题,如果有一个名称冲突比如你只关心一些数据的最新版本,那么那里有大概没有问题,或者如果文件名不是真正重要的只是文件的内容,但它仍然是不好的做法。

您可以在TMP目录使用命名临时文件,然后将文件一旦通过验证其最终位置。或者你可以检查文件名不存在,像这样:

file.name = slugify(myfile.filename)
name, ext = os.path.splitext(file.name)
while os.path.exists(os.path.join(permanent_store, file.name)):
    name += '_'
    file.name = name + ext

raw_file = os.path.join(permanent_store, file.name)

在slugify方法将用于整理文件名...

其他提示

我只是想让任何人来到这里寻找答案,要知道, Allesandro Molina's伟大的图书馆 是的最好回答这个问题。

它解决了两个命名和复制的问题,并将很好地为您的TurboGears应用程序。你可以用它与MongoDB GridFS,因为在这个例子:

from depot.manager import DepotManager

# Configure a *default* depot to store files on MongoDB GridFS
DepotManager.configure('default', {
    'depot.backend': 'depot.io.gridfs.GridFSStorage',
    'depot.mongouri': 'mongodb://localhost/db'
})

depot = DepotManager.get()

# Save the file and get the fileid
fileid = depot.create(open('/tmp/file.png'))

# Get the file back
stored_file = depot.get(fileid)
print stored_file.filename
print stored_file.content_type

或者你可以很容易地创造附件领域中的你 SQLAlchemy 模型,如:

from depot.fields.sqlalchemy import UploadedFileField

class Document(Base):
    __tablename__ = 'document'

    uid = Column(Integer, autoincrement=True, primary_key=True)
    name = Column(Unicode(16), unique=True)

    content = Column(UploadedFileField)

...然后,储存文件与附件(来源可以是文件或字节)变得容易,因为:

doc = Document(name=u'Foo', content=open('/tmp/document.xls'))
DBSession.add(doc)

仓库支持 LocalFileStorage, MongoDB's GridFSStorage, 和亚马逊的 S3Storage.而且,至少是对文件存储在本地,并在S3, fileid 将产生 uuid.uuid1().

我不很了解的TurboGears知道它是否能提供一切努力避免以下,但在我看来,这个代码是充满了危险。有可能的恶意用户覆盖(或创建)的任何文件,所述的TurboGears蟒过程必须写访问。

如果什么asset_dirname/tmpfile.filename的内容是../../../../../../../etc/passwd和文件root::0:0:root:/root:/bin/bash的内容?在UNIX环境中,该代码(权限待定)将打开截断模式的文件/tmp/../../../../../../../etc/passwd然后复制上传文件到它的内容 - 有效覆盖系统密码文件,并指定root用户没有密码。想必有一些可以做一个Windows机器太讨厌的东西。

行,这是一个极端的例子,需要蟒正在作为root(没有一个这样做,是吗?)。即使蟒运行为低priveleged用户,以前上传的文件可以在将被覆盖。

要概括,不信任用户的输入,在这种情况下,用户提供的文件名是在file.filename可用。

是不是TurboGears的只是演员挂架?你可能出现退房的帮助:

http://wiki.pylonshq.com/display/pylonsdocs /表格+处理#文件的上载

但是,仍含有潜在的安全漏洞,mhawke提到:

os.path.join(permanent_store, myfile.filename.lstrip(os.sep))

与上述相同,如果真的莫名其妙的文件名是../../../../../etc/passwd那么你可以替换该文件...

所以,你可以只得到实际的文件名,像这样:

os.path.join(permanent_store, myfile.filename.split(os.sep).pop())

WERKZEUG具有很好的辅助函数用于固定所谓的 secure_filename 。我想你可以采纳和使用它。

有关如何走,我第二次已经给了很好的答案。

这是我的2便士,对存储的文件命名。

的确节省使用原来的名称可能会导致一个漏洞的文件。 在仅使用I使原来的名称的,如果在所有,是暗示的mime类型检测。

反正文件保存应给予唯一的名称,由创纪录的身份或类似的东西,和应用程序目录的拥有者,谁是一个普通用户,或者在其他一些存储服务的控制下保持在一个地方,作为上述贮存库等

它的跨语言良好的系统设计的问题:)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top