Я работаю с AkaDAV, сервером WebDAV на основе Twisted, и я пытаюсь поддержать полный набор тестов лакмусовой бумажки. Я в настоящее время застрял в http-подсетей.
В частности, я могу запустить:
$ TESTS=http litmus http://localhost:8080/steder/
-> running 'http':
0. init.................. pass
1. begin................. pass
2. expect100............. FAIL (timeout waiting for interim response)
3. finish................ pass
Этот тест в основном делает следующее:
Выполните следующие действия:
PUT/steder/litmus/expect100 HTTP/1.1 Host: localhost: 8080 Content-Length: 100 Expect: 100-continue
ожидает ответа HTTP/1.1 100 Continue
ответ.
Сложная вещь здесь заключается в том, что похоже, что этот запрос PUT никогда не делает его Twisted. Как проверка curl -X PUT...
я подтвердил, что запросы PUT, выданные через curl -X PUT...
работают, так что кажется, что что-то особенное в этом curl -X PUT...
.
Любые идеи, что я могу делать неправильно? Я рад поделиться исходным кодом, если это поможет.
РЕДАКТИРОВАТЬ:
После немного более twisted.web
вокруг, кажется, что это известная проблема twisted.web
: http://twistedmatrix.com/trac/ticket/4673
Кто-нибудь знает об обходном пути?
После некоторого исследования достаточно ясно, как изменить реализацию протокола HTTP для поддержки этого варианта использования. Похоже, что официальное исправление скоро будет в Twisted, но пока я использую это как обходной путь.
Просто twhttp.HTTPFactory
этот код, прежде чем создавать экземпляр вашего Site
(или twhttp.HTTPFactory
):
from twisted.web import http
class HTTPChannelWithExpectContinue(http.HTTPChannel):
def headerReceived(self, line):
"""Just extract the header and handle Expect 100-continue:
"""
header, data = line.split(':', 1)
header = header.lower()
data = data.strip()
if (self._version=="HTTP/1.1" and
header == 'expect' and data.lower() == '100-continue'):
self.transport.write("HTTP/1.1 100 Continue\r\n\r\n")
return http.HTTPChannel.headerReceived(self, line)
http.HTTPFactory.protocol = HTTPChannelWithExpectContinue
Я предполагаю, что если вам нужны другие модификации на уровне протокола, вы можете использовать этот же метод для их исправления. Это не обязательно симпатично, но это работает для меня.
expect continue
состоит в том, чтобы дать серверу возможность отклонить возможно большой запрос до того, как клиент начал его отправлять, экономя пропускную способность для обеих сторон. Еще лучшим решением может быть вызов метода в протоколе, который может возвращать true или false, чтобы указать, что запрос должен быть принят (по умолчанию, который всегда возвращает true)