How can I set a custom response header for pylons static (public) files?

白昼怎懂夜的黑 提交于 2020-01-20 06:54:26

问题


How do I add a custom header to files pylons is serving from public?


回答1:


a) Let your webserver serve files from /public instead of paster and configure it to pass some special headers.

b) Add a special route and serve the files yourself ala

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

c) maybe there is a way to overwrite headers and i just dont know how.




回答2:


With a recent version of route, you can use the 'Magic path_info' feature, and follow the documentation from here to write your controller so it calls paster.DirectoryApp.

In my project, I wanted to serve any file in the public directory, including subdirs, and ended with this as controller, to be able to override 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')



回答3:


In a standard Pylons setup, the public files are served from a StaticUrlParser. This is typically setup in your config/middleware.py:make_app() function

You need to subclass the StaticUrlParser like Antonin ENFRUN describes, though calling it a Controller is confusing because it's doing a different purpose. Add something like the following to the top of the 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')

then replace StaticUrlParser in config/middleware.py:make_app() with HeaderUrlParser

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

becomes

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



回答4:


A simpler way to use FileApp for streaming, based on the pylons book. The code below assumes your route provides some_file_identifier, but the other two variables are "magic" (see explanation after code).

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 automatically gives you the wsgi environ and start_response variables if you have variables of those names in your method signature. You should not need to set or munge headers otherwise, but if you do you can use the abilities built in to FileApp to achieve this.



来源:https://stackoverflow.com/questions/836191/how-can-i-set-a-custom-response-header-for-pylons-static-public-files

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!