1

这个问题与这个有关。
请阅读克里斯在那里描述的问题。我会缩小范围:如果文件名是 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))])

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

4

2 回答 2

2

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

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

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

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

如果这完全失败,您始终可以通过pycurl.READFUNCTION.

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

我破解了你的代码片段,我有这个,它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 之间编码不同的情况。

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

于 2013-06-09T12:21:51.307 回答
2

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

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

于 2013-06-07T22:32:08.817 回答