Ошибка Python BadStatusLine на определенных запросах DELETE - PullRequest
1 голос
/ 07 ноября 2011

Я пытаюсь использовать python-rest-client (http://code.google.com/p/python-rest-client/wiki/Using_Connection) для тестирования некоторых веб-сервисов RESTful.Поскольку я только учусь, я нацеливаю свои тесты на примеры сервисов, предоставляемых на http://www.predic8.com/rest-demo.htm.

. У меня нет проблем с созданием записей, обновлением записей или получением записей (запросы POST и GET).Когда я пытаюсь сделать запрос УДАЛИТЬ, это не удается.Я могу использовать клиент Firefox REST для выполнения запросов DELETE, и они работают.Я также могу делать запросы DELETE на другие сервисы, но я сводил с ума, пытаясь понять, почему это не работает в этом случае.Я использую Python 3 с обновленным Httplib2, но я также пробовал Python 2.5, чтобы я мог использовать python-rest-client с включенной версией Httplib2.Я вижу ту же проблему в любом случае.

Код прост, соответствует документированному использованию:

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: ''

Что ломается?Что мне с этим делать?На самом деле, я бы согласился на совет по его устранению.Я изменил домен в своем скрипте и указал его на своем компьютере, чтобы я мог просмотреть запрос.Я просмотрел / изменил запросы Firefox в BurpProxy, чтобы они соответствовали моим запросам скрипта.Измененные запросы Burp по-прежнему работают, а запросы Python по-прежнему не работают.

Ответы [ 2 ]

4 голосов
/ 07 ноября 2011

Очевидно, проблема в том, что сервер ожидает, что для запросов 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()

Я напечатал там параметр заголовков, чтобы подтвердить, что длины контента там не было, затем добавил:

if(method == 'DELETE'):
     headers['Content-Length'] = '0'

перед запросом.

Я думаю, что реальный ответ таков:Служба шаткая, но, по крайней мере, я немного лучше узнал httplib2.Я видел некоторых других смущенных людей, которые искали помощи с REST и Python, так что, надеюсь, я не единственный, кто получил что-то от этого.

1 голос
/ 07 ноября 2011

Следующий скрипт правильно выдает 404 ответ от сервера:

#!/usr/bin/env python3
import http.client 

h = http.client.HTTPConnection('www.thomas-bayer.com', timeout=10)
h.request('DELETE', '/sqlrest/CUSTOMER/85', headers={'Content-Length': 0})
response = h.getresponse()
print(response.status, response.version)
print(response.info())
print(response.read()[:77])

python -V => 3.2


curl -X DELETE http://www.thomas-bayer.com/sqlrest/CUSTOMER/85
curl: (52) Empty reply from server

Строка состояния не является обязательной ; HTTP-сервер должен вернуть его. Или, по крайней мере, отправьте 411 Длина требуется ответ.

curl -H 'Content-length: 0' -X DELETE \
  http://www.thomas-bayer.com/sqlrest/CUSTOMER/85

Возвращает правильно 404.

...