【问题标题】:Pycurl: uploading files with filenames in UTF-8Pycurl:上传带有 UTF-8 文件名的文件
【发布时间】:2013-06-04 07:45:57
【问题描述】:

这个问题与this one有关。
请阅读克里斯在那里描述的问题。我会缩小范围:如果文件名是 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),即使是俄语字符也是不允许的。
你能帮忙吗?谢谢!

【问题讨论】:

  • 请将您的代码 sn-p 扩展为独立测试。不清楚filename是什么,我想一定是unicode; field 是什么,设置了哪些其他选项...

标签: python curl unicode utf-8 pycurl


【解决方案1】:

这很容易回答,更难解决:

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

【讨论】:

  • Hej @Daniel,感谢您的回答!我看到你是 Libcurl 的开发者。所以也许你能解决这个问题,让它接受 utf-8 名称?如果没有,也许有办法覆盖它?谢谢!
  • 1.我回答这个问题。如果您想讨论 libcurl 的详细信息,这里不适合 2. 如果您还有其他问题,请提交第二个问题或将其发送到 libcurl 邮件列表。
【解决方案2】:

把这个问题分解成2个部分:

  1. 告诉pycurl打开哪个文件来读取文件数据
  2. 将正确编码的文件名发送到服务器

这些可能是也可能不是相同的编码。

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

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

对于2,了解文件上传过程中如何传输文件名,example。我没有一个好的链接,我只知道这不是微不足道的,例如当涉及到非常长的文件名时。

我破解了你的代码 sn-p,我有这个,它至少适用于 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 之间编码不同的情况。

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

【讨论】:

  • 感谢您的回答!我已经成功完成了第 1 步,但是第 2 步没有任何编码的骰子......它总是说错误 26。有什么想法吗?
  • CURLE_READ_ERROR (26) There was a problem reading a local file or an error returned by the read callback. 看起来你没有解决组件 1。让我尝试重现。
猜你喜欢
  • 2017-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-05
  • 1970-01-01
  • 2013-12-22
  • 2016-07-27
相关资源
最近更新 更多