如何在Twisted Web中使用“Expect: 100-continue”头?

1 投票
1 回答
1644 浏览
提问于 2025-04-17 00:26

我最近在使用AkaDAV,这是一个基于Twisted的WebDAV服务器,我正在尝试支持完整的litmus测试套件。目前我卡在了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

这个测试基本上做了以下几件事:

  1. 打开一个与WebDAV服务器的连接
  2. 发送以下PUT请求:

    PUT /steder/litmus/expect100 HTTP/1.1
    Host: localhost:8080
    Content-Length: 100
    Expect: 100-continue

  3. 等待一个响应,内容是HTTP/1.1 100 Continue

  4. 上传100字节的内容

这里让人困惑的是,这个PUT请求似乎根本没有到达Twisted服务器。为了确认这一点,我用curl -X PUT ...发送的PUT请求是有效的,所以看起来这个测试用例有些特别。

有没有人知道我可能做错了什么?如果需要,我可以分享源代码。

编辑:

经过进一步的查找,似乎这是一个已知的twisted.web问题:http://twistedmatrix.com/trac/ticket/4673

有没有人知道解决办法?

1 个回答

1

经过进一步调查,我发现如何修改HTTP协议的实现来支持这个用例。看起来官方的修复很快就会在Twisted中推出,但在此之前,我使用这个方法作为临时解决方案。

只需在创建你的Site(或者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

我想如果你需要在协议层面进行其他修改,也可以用同样的方法来修补。这方法可能不是特别完美,但对我来说有效。

撰写回答