我目前正在处理一段由其他人编写的代码。它使用httplib
向服务器发出请求。它以正确的格式提供所有数据,例如消息正文、标头值等。
问题是,每次它试图发送POST请求时,数据都在那里——我可以在客户端看到它,但没有任何数据到达服务器。我已经通读了库规范,用法似乎是正确的。
提取的库调用如下:
import httplib
conn = httplib.HTTPConnection('monkeylabs.pl', 80)
conn.connect()
request = conn.putrequest('POST', '/api/snippet/')
headers = {}
headers['Content-Type'] = 'application/json'
headers['User-Agent'] = 'Envjs/1.618 (SpyderMonkey; U; Linux x86_64 2.6.38-10-generic; pl_PL.utf8; rv:2.7.1) Resig/20070309 PilotFish/1.3.pre03'
headers['Accept'] = '*/*'
for k in headers:
conn.putheader(k, headers[k])
conn.endheaders()
conn.send('[{"id":"route"}]')
resp = conn.getresponse()
print resp.status
print resp.reason
print resp.read()
conn.close()
这是已知的问题吗?我使用的是Python 2.7。不知道如何检查httplib的版本。
请不要建议用httplib交换其他东西,除非它真的很相似(可能是httplib2)。正如我所说,这个代码不是我的,它的数量比我刚刚发布的要多得多。重构它会导致一个大问题。我对任何可靠的解决方案都感兴趣。
编辑
调试输出:
send: 'POST /api/snippet/ HTTP/1.1rnHost: monkeylabs.plrnAccept-Encoding: identityrnContent-Type: application/jsonrnAccept: */*rnUser-Agent: Envjs/1.618 (SpyderMonkey; U; Linux x86_64 2.6.38-10-generic; pl_PL.utf8; rv:2.7.1) Resig/20070309 PilotFish/1.3.pre03rnrn[{"id":"route"}]'
reply: 'HTTP/1.0 201 CREATEDrn'
header: Date: Fri, 10 Jun 2011 23:54:00 GMT
header: Server: WSGIServer/0.1 Python/2.7.1+
header: Vary: Cookie
header: Content-Type: application/json
header: Content-Length: 0
201
CREATED
请注意,回复后的信息实际上是关于服务器回复,而不是请求本身,在这种情况下,请求本身是空的。主要原因是请求主体本身是空的,我可以通过获取日志来观察:
[11/Jun/2011 01:54:00] "POST /api/snippet/ HTTP/1.1" 201 0
这三条线:
``
<QueryDict: {}>
<QueryDict: {}>
出:
print '`%s`' % request.raw_post_data
print request.GET
print request.POST
在Django服务器上。因此,它似乎试图发送尸体,但最终没有发送。
编辑(2)
好吧,我做了一个转储,它确实告诉我,在浏览器发送的消息中,有一个名为"内容长度"的附加参数,在库的常规使用中被省略了。愚蠢的我。
putrequest
方法不会自动添加Content-Length标头,您需要自己添加或使用request
方法。
将其添加到for
循环上方的代码中:
headers['Content-Length'] = "%d"%(len('[{"id":"route"}]'))
尝试添加:
conn.set_debuglevel(1)
这样您就可以看到实际发生了什么。
您检查httplib文档了吗?httplib是一个标准的Python库,Python也非常擅长拥有在线文档:http://docs.python.org/library/httplib.html
该页面中的示例:
>>> import httplib, urllib
>>> params = urllib.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
>>> headers = {"Content-type": "application/x-www-form-urlencoded",
... "Accept": "text/plain"}
>>> conn = httplib.HTTPConnection("musi-cal.mojam.com:80")
>>> conn.request("POST", "/cgi-bin/query", params, headers)
>>> response = conn.getresponse()
>>> print response.status, response.reason
200 OK
>>> data = response.read()
>>> conn.close()
您的示例似乎比这更多,如果您阅读API文档(例如putrequest
),您会发现您在示例中使用了错误的方法。具体来说,默认情况下,它会自动添加Accept标头。
试着让你的代码更像函数示例,也试着理解你的代码和工作示例中使用的调用。