如何在Python + twisted中检测HTTP请求?

3 投票
2 回答
1479 浏览
提问于 2025-04-16 02:28

我正在学习使用 Python 的 twisted 10 进行网络编程。在下面的代码中,有没有办法在接收到数据时检测到 HTTP 请求?还有,能从中提取出域名、子域名和端口值吗?如果不是 HTTP 数据就丢弃它?

from twisted.internet import stdio, reactor, protocol

from twisted.protocols import basic

import re



class DataForwardingProtocol(protocol.Protocol):

    def _ _init_ _(self):

        self.output = None

        self.normalizeNewlines = False



    def dataReceived(self, data):

        if self.normalizeNewlines:

            data = re.sub(r"(\r\n|\n)", "\r\n", data)

        if self.output:

            self.output.write(data)



class StdioProxyProtocol(DataForwardingProtocol):

    def connectionMade(self):

        inputForwarder = DataForwardingProtocol( )

        inputForwarder.output = self.transport

        inputForwarder.normalizeNewlines = True

        stdioWrapper = stdio.StandardIO(inputForwarder)

        self.output = stdioWrapper

        print "Connected to server.  Press ctrl-C to close connection."



class StdioProxyFactory(protocol.ClientFactory):

    protocol = StdioProxyProtocol



    def clientConnectionLost(self, transport, reason):

        reactor.stop( )



    def clientConnectionFailed(self, transport, reason):

        print reason.getErrorMessage( )

        reactor.stop( )



if __name__ == '_ _main_ _':

    import sys

    if not len(sys.argv) == 3:

        print "Usage: %s host port" % _ _file_ _

        sys.exit(1)



    reactor.connectTCP(sys.argv[1], int(sys.argv[2]), StdioProxyFactory( ))

    reactor.run( )

2 个回答

1

根据你所尝试的内容,我觉得下面这个链接是最简单的选择:

http://twistedmatrix.com/documents/10.0.0/api/twisted.web.proxy.html

这是一个用于构建HTTP代理的twisted类。它可以让你拦截请求,查看请求的目的地和发送者。你还可以查看所有的头信息和来回传输的内容。看起来你是想重新编写HTTP协议和twisted已经为你提供的代理类。希望这对你有帮助。

3

protocol.dataReceived 是你正在重写的方法,但这个方法太底层了,不能直接用来处理你想做的事情,因为你没有进行智能缓存——根据我刚才引用的文档,

每当接收到数据时都会调用这个方法。

你可以用这个方法把数据转换成更高级别的消息。通常,在收到每个完整的协议消息后,会有某个回调被调用。

参数

data

一个长度不确定的字符串。请记住,你可能需要缓存一些数据,因为可能会接收到部分(或多个)协议消息!我建议对协议的单元测试调用这个方法时,使用不同大小的数据块,甚至可以逐字节测试。

你似乎完全忽视了文档中这个重要的部分。

你可以考虑使用 LineReceiver.lineReceived(当然要继承自 protocols.basic.LineReceiver),这样可以利用HTTP请求是以“行”的形式发送的这个特点——你仍然需要把作为多行发送的头部合并起来,因为正如这个教程所说:

以空格或制表符开头的头部行实际上是前一个头部行的一部分,为了便于阅读而折叠成多行。

一旦你得到了格式良好/解析过的响应(可以考虑研究一下 twisted.web的源代码,看看可以怎么做),

从中获取域名、子域名和端口值?

现在 Host 头部(参见 RFC 第14.23节)就是包含这些信息的地方。

撰写回答