如何将自定义标头添加到 pylons 从公共提供的文件中?
4 回答
a) 让您的网络服务器从 /public 而非 paste 提供文件,并将其配置为传递一些特殊的标头。
b)添加一个特殊的路线并自己提供文件ala
class FilesController(BaseController):
def download(self, path)
fapp = FileApp( path, headers=self.get_headers(path) )
return fapp(request.environ, self.start_response)
c)也许有一种方法可以覆盖标题,我只是不知道如何。
在标准 Pylons 设置中,公共文件由 StaticUrlParser 提供。这通常在您的 config/middleware.py:make_app() 函数中设置
您需要像 Antonin ENFRUN 所描述的那样对 StaticUrlParser 进行子类化,尽管称它为 Controller 会令人困惑,因为它的用途不同。在 config/middleware.py 的顶部添加如下内容:
from paste.fileapp import FileApp
from paste.urlparser import StaticURLParser
class HeaderUrlParser(StaticURLParser):
def make_app(self, filename):
headers = # your headers here
return FileApp(filename, headers, content_type='application/octetstream')
然后将 config/middleware.py:make_app() 中的 StaticUrlParser 替换为 HeaderUrlParser
static_app = StaticURLParser(config['pylons.paths']['static_files'])
变成
static_app = HeaderURLParser(config['pylons.paths']['static_files'])
使用最新版本的路由,您可以使用“ Magic path_info ”功能,并按照此处的文档编写您的控制器,以便它调用 paste.DirectoryApp。
在我的项目中,我想提供公共目录中的任何文件,包括子目录,并以此作为控制器结束,以便能够覆盖 content_type :
import logging
from paste.fileapp import FileApp
from paste.urlparser import StaticURLParser
from pylons import config
from os.path import basename
class ForceDownloadController(StaticURLParser):
def __init__(self, directory=None, root_directory=None, cache_max_age=None):
if not directory:
directory = config['pylons.paths']['static_files']
StaticURLParser.__init__(self, directory, root_directory, cache_max_age)
def make_app(self, filename):
headers = [('Content-Disposition', 'filename=%s' % (basename(filename)))]
return FileApp(filename, headers, content_type='application/octetstream')
一种使用 FileApp 进行流式传输的更简单方法,基于 pylons book。下面的代码假定您的路线提供some_file_identifier
,但其他两个变量是“魔术”(参见代码后的解释)。
class MyFileController(BaseController):
def serve(self, environ, start_response, some_file_identifier):
path = self._convert_id_to_path(some_file_identifier)
app = FileApp(path)
return app(environ, start_response)
如果您的方法签名中有这些名称的变量,Pylons 会自动为您提供 wsgienviron
和变量。start_response
否则,您不需要设置或删除标头,但如果您这样做,您可以使用FileApp 内置的功能来实现这一点。