当内容类型为“application/xml”时,如何使用 httplib 发布非 ASCII 字符

2023-11-23

我已经在 Python 2.7 中实现了 Pivotal Tracker API 模块。这关键跟踪器 API期望 POST 数据是 XML 文档,并且“application/xml”是内容类型。

我的代码使用 urlib/httplib 来发布文档,如下所示:

    request = urllib2.Request(self.url, xml_request.toxml('utf-8') if xml_request else None, self.headers)
    obj = parse_xml(self.opener.open(request))

当 XML 文本包含非 ASCII 字符时,这会产生异常:

File "/usr/lib/python2.7/httplib.py", line 951, in endheaders
  self._send_output(message_body)
File "/usr/lib/python2.7/httplib.py", line 809, in _send_output
  msg += message_body
exceptions.UnicodeDecodeError: 'ascii' codec can't decode byte 0xc5 in position 89: ordinal not in range(128)

据我所知,httplib._send_output 正在为消息有效负载创建一个 ASCII 字符串,大概是因为它期望数据进行 URL 编码 (application/x-www-form-urlencoded)。只要仅使用 ASCII 字符,它就可以与 application/xml 配合使用。

有没有一种简单的方法来发布包含非 ASCII 字符的应用程序/xml 数据,或者我是否必须跳过一些麻烦(例如,使用 Twistd 和 POST 有效负载的自定义生成器)?


您正在混合 Unicode 和字节串。

>>> msg = u'abc' # Unicode string
>>> message_body = b'\xc5' # bytestring
>>> msg += message_body
Traceback (most recent call last):
  File "<input>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc5 in position 0: ordinal \
not in range(128)

要修复它,请确保self.headers内容被正确编码,即所有键、值headers应该是字节串:

self.headers = dict((k.encode('ascii') if isinstance(k, unicode) else k,
                     v.encode('ascii') if isinstance(v, unicode) else v)
                    for k,v in self.headers.items())

注意:标头的字符编码与正文的字符编码无关,即 xml 文本可以独立编码(从 http 消息的角度来看,它只是一个八位字节流)。

同样适用于self.url——如果它有unicode类型;将其转换为字节串(使用“ascii”字符编码)。


HTTP 消息由起始行、“标头”、空行和可能的消息正文组成 so self.headers用于标题,self.url用于起始行(http 方法在此处),并且可能用于Hosthttp 标头(如果客户端是 http/1.1),XML 文本转到消息正文(作为二进制 blob)。

使用 ASCII 编码始终是安全的self.url(IDNA 可用于非 ASCII 域名 — 结果也是 ASCII)。

这是什么rfc 7230 关于 http 的说明headers字符编码:

从历史上看,HTTP 允许字段内容包含文本 ISO-8859-1 字符集 [ISO-8859-1],仅支持其他字符集 通过使用 [RFC2047] 编码。实际上,大多数 HTTP 标头 字段值仅使用 US-ASCII 字符集 [USASCII] 的子集。 新定义的标头字段应该将其字段值限制为 US-ASCII 八位字节。接收者应该处理字段中的其他八位字节 内容(obs-text)作为不透明数据。

要将 XML 转换为字节串,请参阅application/xml编码注意事项:

建议所有 XML MIME 实体使用不带 BOM 的 UTF-8。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当内容类型为“application/xml”时,如何使用 httplib 发布非 ASCII 字符 的相关文章

随机推荐