我一直在试图找出用Turbogears 2管理文件上传的“最佳实践”,但到目前为止还没有找到任何例子。我已经想出了一种上传文件的方法,但我不确定它对我们有多可靠。
另外,获取上传文件名称的好方法是什么?
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 = UUID。
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()发布于 2010-03-05 16:07:43
@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方法将用于整理文件名...
发布于 2015-04-20 17:39:58
我只想让任何来这里寻找答案的人都知道,Allesandro Molina的伟大的库Depot构成了这个问题的最佳答案。
它解决了命名和复制问题,并且可以很好地集成到您的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)Depot支持LocalFileStorage、MongoDB的GridFSStorage和亚马逊的S3Storage。而且,至少对于存储在本地和S3中的文件,fileid将由uuid.uuid1()生成。
发布于 2010-03-04 10:04:54
我对Turbogears了解不多,也不知道它是否能提供任何东西来避免以下情况,但在我看来,这段代码充满了危险。恶意用户可能会覆盖(或创建) Turbogears python进程有权写入的任何文件。
如果asset_dirname为/tmp,file.filename的内容为../../../../../../../etc/passwd,文件的内容为root::0:0:root:/root:/bin/bash,该怎么办?在UNIX环境中,此代码(权限挂起)将以截断模式打开文件/tmp/../../../../../../../etc/passwd,然后将上载文件的内容复制到其中-有效地覆盖系统的密码文件并指定不带密码的根用户。大概在Windows机器上也可以做一些令人讨厌的事情。
好吧,这是一个极端的例子,它要求python以root身份运行(没有人这样做,不是吗?)即使python是以低权限用户身份运行的,以前上传的文件也可能被随意覆盖。
总而言之,不要相信用户输入,在这种情况下,用户提供的文件名在file.filename中可用。
https://stackoverflow.com/questions/2375290
复制相似问题