我正在尝试使用python-rest-client(http://code.google.com/p/python-rest-client/wiki/Using_Connection)来执行一些RESTful Web服务的测试。由于我刚刚学习,我一直把测试指向http://www.predic8.com/rest-demo.htm提供的样本服务。
我在创建条目,更新条目或检索条目(POST和GET请求)方面没有任何问题。当我尝试发出DELETE请求时,它会失败。我可以使用Firefox REST Client执行DELETE请求并且它们可以正常工作。我也可以在其他服务上发出DELETE请求,但是我一直在疯狂地试图弄清楚为什么它在这种情况下不起作用。我正在使用Python 3和更新的Httplib2,但我也尝试使用Python 2.5,以便我可以使用包含Httplib2版本的python-rest-client。在任何一种情况下我都会看到同样的问题。
代码很简单,与记录的用法相匹配:
from restful_lib import Connection
self.base_url = "http://www.thomas-bayer.com"
self.conn = Connection(self.base_url)
response = self.conn.request_delete('/sqlrest/CUSTOMER/85')
我查看了来自浏览器工具和我的代码的结果HTTP请求,我看不出为什么一个有效,另一个没有。这是我收到的痕迹:
Traceback (most recent call last):
File "/home/fmk/python/rest-client/src/TestExampleService.py", line 68, in test_CRUD
self.Delete()
File "/home/fmk/python/rest-client/src/TestExampleService.py", line 55, in Delete
response = self.conn.request_delete('/sqlrest/CUSTOMER/85')
File "/home/fmk/python/rest-client/src/restful_lib.py", line 64, in request_delete
return self.request(resource, "delete", args, headers=headers)
File "/home/fmk/python/rest-client/src/restful_lib.py", line 138, in request
resp, content = self.h.request("%s://%s%s" % (self.scheme, self.host, '/'.join(request_path)), method.upper(), body=body, headers=headers )
File "/home/fmk/python/rest-client/src/httplib2/__init__.py", line 1175, in request
(response, content) = self._request(conn, authority, uri, request_uri, method, body, headers, redirections, cachekey)
File "/home/fmk/python/rest-client/src/httplib2/__init__.py", line 931, in _request
(response, content) = self._conn_request(conn, request_uri, method, body, headers)
File "/home/fmk/python/rest-client/src/httplib2/__init__.py", line 897, in _conn_request
response = conn.getresponse()
File "/usr/lib/python3.2/http/client.py", line 1046, in getresponse
response.begin()
File "/usr/lib/python3.2/http/client.py", line 346, in begin
version, status, reason = self._read_status()
File "/usr/lib/python3.2/http/client.py", line 316, in _read_status
raise BadStatusLine(line)
http.client.BadStatusLine: ''
什么打破?我该怎么办?实际上,我会接受调试它的建议。我已经在我的脚本中更改了域并将其指向我自己的机器,因此我可以查看请求。我查看/修改了BurpProxy中的Firefox请求,使它们与我的脚本请求相匹配。修改后的Burp请求仍然有效,Python请求仍然没有。
答案 0 :(得分:4)
显然问题是服务器期望DELETE请求有一些消息体。这是DELETE的一个不寻常的期望,但是通过在头文件中指定Content-Length:0,我能够成功执行DELETE。
在某个地方(在python-rest-client或httplib2中),如果我尝试这样做,Content-Length标头就会被删除:
from restful_lib import Connection
self.base_url = "http://www.thomas-bayer.com"
self.conn = Connection(self.base_url)
response = self.conn.request_delete('/sqlrest/CUSTOMER/85', headers={'Content-Length':'0'})
为了证明这个概念,我在堆栈跟踪中找到了请求发生的地方:
File "/home/fmk/python/rest-client/src/httplib2/__init__.py", line 897, in _conn_request
response = conn.getresponse()
我在那里打印了headers参数以确认内容长度不存在,然后我添加了:
if(method == 'DELETE'):
headers['Content-Length'] = '0'
在请求之前。
我认为真正的答案是服务很不稳定,但至少我对httplib2了解得更好一点。我见过其他一些困惑的人在寻求REST和Python的帮助,所以希望我不是唯一能从中得到一些东西的人。