Django/httplib:使用httplib传输request.raw_post_data

2 投票
1 回答
966 浏览
提问于 2025-04-16 20:51

"啊啊啊,求助啊!!!"

我现在想做的事情是……

我有一个Django网站 site1,需要访问另一个服务 site2 的API。不过,为了做到这一点,site1 需要使用自己的登录凭证等等……

所以我写了一个小的Django应用,它复制了 site2 的网址,但在后台使用 httplib2 来几乎一模一样地发送请求(只是进行身份验证之类的)。在大多数情况下,它工作得很好,实际上以前在所有情况下都很好用(我也不知道是什么导致它坏掉的,可能是Python从2.6升级到2.7时出了问题)。

为了按原样发送POST/PUT数据,我是这样获取的:

post_data = request.raw_post_data

然后用httplib2发送:

response, content = c.request(
    url,
    method,
    post_data,
    headers=headers,
)

问题出现在发送包含二进制数据(比如图片)的 multipart-data 时。httplibhttplib2 是基于它构建的)在构建请求字符串时,试图把我的 post_data 和一些生成的头部信息拼接在一起。而且似乎 request.raw_post_datastring 类型,而生成的东西是 unicode。所以,它试图解码我的 post_data(里面有二进制数据),结果就出错了!!!

参考 httplib 第807行:

if isinstance(message_body, str):
    msg += message_body

这是通过 request.raw_post_data 获取的 message_body 的一部分:

'-----------------------------697585321193462802080194682\r\nContent-Disposition: form-data; name="_method"\r\n\r\nPUT\r\n-----------------------------697585321193462802080194682\r\nContent-Disposition: form-data; name="jpegPhoto"; filename="crap.jpg"\r\nContent-Type: image/jpeg\r\n\r\n\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x01\x00H\x00H\x00\x00\xff\xfe\x00\x13Created with GIMP\xff\xdb\x00C\x00\x05\x03\x04\x04\x04\x03\x05\x04\x04\x04

这是 msg 的内容:

u'POST /user/spiq/?username=spiq HTTP/1.1\r\nContent-Length: 40307\r\naccept-language: en-us,en;q=0.5\r\naccept-encoding: gzip, deflate\r\nhost: localhost:8000\r\naccept: application/json\r\nuser-agent: Mozilla/5.0 (X11; Linux x86_64; rv:5.0) Gecko/20100101 Firefox/5.0\r\naccept-charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\nconnection: keep-alive\r\nreferer: \r\ncookie: csrftoken=d9a3e014e5e366ee435b27ae7fc122af; sessionid=d5492a8d640e346b8ca56fa87e5cc439\r\ncontent-type: multipart/form-data\r\n\r\n'

所以基本上这事情是没救了……

有没有什么建议我该怎么做?我能不能在不解码的情况下把我的 post_data 转换成 unicode

1 个回答

1

根据这个链接:http://bugs.python.org/issue11898#msg138059,看起来如果你能把 url 这个参数转换成 str(字符串),那么你可能就没问题了。

撰写回答