How can I use "Expect: 100-continue" header in Twisted Web?
I've been working with AkaDAV, a Twisted based WebDAV server, and I'm trying to support the full litmus test suite. I'm currently stuck on the http sub-suite.
Specifically, I can run:
$ TESTS=http litmus http://localhost:8080/steder/
-> running `http':
0. init.................. pass
1. begin................. pass
2. expect100............. FAIL (timeout waiting for interim resp开发者_运维问答onse)
3. finish................ pass
This test basically does the following:
- Open a socket to the WebDAV server
Issue the following PUT:
PUT /steder/litmus/expect100 HTTP/1.1 Host: localhost:8080 Content-Length: 100 Expect: 100-continue
waits for a response
HTTP/1.1 100 Continue
response.- uploads 100 byte content payload
The confusing thing here is that it looks like this PUT request never makes it to Twisted. As a sanity check I've confirmed that PUT requests issued through curl -X PUT ...
work so it seems like there's something special about this testcase.
Any ideas what I may be doing wrong? I'm happy to share sourcecode if that helps.
EDIT:
After a little more looking around it appears that this is a known twisted.web
issue: http://twistedmatrix.com/trac/ticket/4673
Does anyone know of a workaround?
After some more investigation it's pretty clear how to modify the HTTP protocol implementation to support this use case. It looks like the official fix will be in Twisted soon but in the meantime I'm using this as a workaround.
Just include this code before you instantiate your Site
(or t.w.http.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
I imagine if you needed other modifications at the protocol level you could use this same method to patch them in as well. It ain't necessarily pretty but it works for me.
精彩评论