Pycurl:上传文件名为UTF-8的文件

时间:2013-06-07 22:04:34

标签: python curl unicode utf-8 pycurl

此问题与this one有关 请阅读Chris在那里描述的问题。我将它缩小:如果文件名是utf-8编码并且包含的​​字符不在非unicode程序支持的范围内,则会出现CURL错误26。 让我解释一下自己:

local_filename = filename.encode("utf-8")
self.curl.setopt(self.curl.HTTPPOST, [(field, (self.curl.FORM_FILE, local_filename, self.curl.FORM_FILENAME, local_filename))])

我将带有俄语的Windows 7设置为非unicode程序的语言。如果我没有将文件名编码为utf-8(并且将filename,而不是local_filename传递给pycurl(如果文件名包含英语或俄语字符,则一切都完美无缺。但如果有,请说,一个à, - 它会抛出错误26.如果我通过local_filename(如此编码为UTF-8),则不允许使用俄语字符。
你能帮忙吗?谢谢!

2 个答案:

答案 0 :(得分:2)

这很容易回答,更难修复:

pycurl使用libcurl进行formposting。 libcurl使用plain fopen()打开文件进行发布。因此,您需要告诉libcurl它应该打开并从本地文件系统读取的确切文件名。

答案 1 :(得分:2)

将此问题分解为2个组件:

  1. 告诉pycurl打开哪个文件来读取文件数据
  2. 以正确的编码将文件名发送到服务器
  3. 这些可能是也可能不是相同的编码。

    对于1,使用sys.getfilesystemencoding()将unicode文件名(在整个python代码中正确使用)转换为pycurl / libcurl可以使用fopen()正确打开的字符串。使用strace(linux)或等效的windows osx来验证pycurl正在打开正确的文件路径。

    如果完全失败,您始终可以通过pycurl.READFUNCTION从Python提供文件数据流。

    对于2,了解文件上传过程中文件名的传输方式example。我没有一个很好的联系,我所知道的并不是微不足道的,例如当谈到很长的文件名时。

    我破解了你的代码段,我有这个,它至少可以对nc -vl 5050起作用。

    #!/usr/bin/python
    import pycurl
    c = pycurl.Curl()
    
    filename = u"example-\N{EURO SIGN}.mp3"
    with open(filename, "wb") as f:
        f.write("\0\xfffoobar\x07\xff" * 9)
    
    local_filename = filename.encode("utf-8")
    c.setopt(pycurl.HTTPPOST, [("xxx", (pycurl.FORM_FILE, local_filename, pycurl.FORM_FILENAME, local_filename))])
    c.setopt(pycurl.URL, "http://localhost:5050/")
    c.setopt(pycurl.HTTPHEADER, ["Expect:"])
    c.perform()
    

    我的测试不包括操作系统和HTTP之间编码不同的情况。

    应该足以让你开始,不应该吗?