Как установить настраиваемый заголовок ответа для статических (общедоступных) файлов пилонов?

Как добавить пользовательский заголовок к файлам, которые pylons обслуживает из общего доступа?

4 ответа

a) Позвольте вашему веб-серверу обслуживать файлы из /public вместо paster и настраивать его для передачи некоторых специальных заголовков.

б) Добавить специальный маршрут и обслуживать файлы самостоятельно аля

class FilesController(BaseController):
    def download(self, path)
        fapp = FileApp( path, headers=self.get_headers(path) )
        return fapp(request.environ, self.start_response)

в) возможно, есть способ перезаписать заголовки, и я просто не знаю как.

В стандартной настройке Pylons общедоступные файлы обслуживаются из StaticUrlParser. Обычно это настраивается в вашей config/middleware.py: функция make_app()

Вам нужно создать подкласс StaticUrlParser, как описывает Антонин ENFRUN, хотя называть его контроллером непонятно, потому что он выполняет другую цель. Добавьте что-то вроде следующего в начало файла 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')

затем замените StaticUrlParser в config/middleware.py:make_app() на HeaderUrlParser

    static_app = StaticURLParser(config['pylons.paths']['static_files'])

становится

    static_app = HeaderURLParser(config['pylons.paths']['static_files'])

Более простой способ использовать FileApp для потоковой передачи, основанный на книге пилонов. Код ниже предполагает, что ваш маршрут обеспечивает 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 автоматически дает вам wsgi environ а также start_response переменные, если у вас есть переменные этих имен в сигнатуре вашего метода. В противном случае вам не нужно устанавливать или отключать заголовки, но если вы это сделаете, вы можете использовать для этого встроенные в FileApp возможности.

В последней версии маршрута вы можете использовать функцию " Magic path_info" и следовать документации здесь, чтобы написать свой контроллер так, чтобы он вызывал paster.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')
Другие вопросы по тегам