How to serve static file with a hebrew name in python bottle?

五迷三道 提交于 2020-01-04 02:07:12

问题


I receive a request from the client to download some file from the server. The filename is in Hebrew.

@bottle.get("/download/<folder_name>/<file_name>")
def download(folder_name, file_name):

    file_name =  file_name.decode('utf-8')
    folder_name =  folder_name.decode('utf-8')

    if os.path.exists(os.path.join(folder_name, file_name)):
        return bottle.static_file(file_name, root=folder_name, download=True)

The last line fails :

return bottle.static_file(file_name, root=folder_name, download=True)

I get an exception :

UnicodeEncodeError: 'ascii' codec can't encode characters in position 22-25: ordinal not in range(128)

I have no idea what am i doing wrong here.

Callstack shows the exception derives from python bottle code:

File "C:\Python27\Lib\site-packages\bottle-0.10.9-py2.7.egg\bottle.py", line 1669, in __setitem__
  def __setitem__(self, key, value): self.dict[_hkey(key)] = [str(value)]

Please help.

Regard, Omer.


回答1:


Bottle is trying to set the Content-Disposition header on the HTTP response to attachment; filename=.... This doesn't work for non-ASCII characters, as Bottle handles HTTP headers with str internally... but then even if it didn't, there's no cross-browser-compatible way to set a Content-Disposition with a non-ASCII filename. (Background.)

You could set download='...' to a safe ASCII-only string to override Bottle's default guess (which is using the local filename, containing Unicode).

Alternatively, omit the download argument and rely on the browser guessing the filename from the end of the URL. (This is the only widely compatible way to get a Unicode download filename.) Unfortunately then Bottle will omit Content-Disposition completely, so consider altering the headers on the returned response to include plain Content-Disposition: attachment without a filename. Or perhaps you don't care, if the Content-Type is one that will always get downloaded anyway.




回答2:


In the last line try encoding the unicode string into binary using utf-8 codec:

return bottle.static_file(file_name.encode("utf-8"), root=folder_name.encode("utf-8"), download=True)

From the code you provided, it looks like the bottle.static_file method expects a string in binary format, therfore a default conversion using ascii codec is performed (as seen from the error message). As in your string you use Hebrew characters, which are not part of ascii, the default conversion fails. You need to use codec that supports national alphabets, like the utf-8.

For more information, see Unicode In Python, Completely Demystified




回答3:


send_file parameters must be unicode. Here is solution for bottle 0.5.8:

# -*- coding: utf-8 -*-
from bottle import route, run, request, send_file, WSGIRefServer
@route('/:filename#.*#')
def static_file(filename):
    send_file(filename.decode('utf-8'), root=ur'g:\Folder')
run(server=WSGIRefServer, host='192.168.1.5', port=80)  


来源:https://stackoverflow.com/questions/19978975/how-to-serve-static-file-with-a-hebrew-name-in-python-bottle

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