Как обнаружить HTTP-запрос в python + витой? - PullRequest
3 голосов
/ 07 августа 2010

Я изучаю сетевое программирование с использованием витой 10 в Python. В приведенном ниже коде есть ли способ обнаружить 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 ]

3 голосов
/ 07 августа 2010

protocol.dataReceived , который вы переопределяете, слишком низкоуровневый, чтобы служить цели без умной буферизации, которую вы не делаете - согласно документам, которые я только что процитировал,

Вызывается при получении данных.

Используйте этот метод для перевода в сообщение более высокого уровня.Обычно, некоторый обратный вызов будет сделан после получения каждого полного сообщения протокола.

Параметры

data

строка неопределенной длины.Помните, что вам, вероятно, потребуется буферизовать некоторые данные, так как могут быть получены частичные (или множественные) сообщения протокола!Я рекомендую, чтобы модульные тесты для протоколов вызывали этот метод с разными размерами чанков, вплоть до одного байта за раз.

Вы, похоже, полностью игнорируете эту важную часть документов.

Вместо этого вы могли бы использовать LineReceiver.lineReceived (конечно, наследуя от protocols.basic.LineReceiver), чтобы использовать тот факт, что HTTP-запросы поступают в виде «строк» ​​- вам все равно нужно присоединитьсязаголовки, которые отправляются в несколько строк, так как в этом руководстве говорит:

Строки заголовка, начинающиеся с пробела или табуляции, фактически являются частью предыдущей строки заголовка, сложенной в несколько строкдля легкого чтения.

Как только у вас получится хорошо отформатированный / проанализированный ответ (рассмотрите возможность изучения источников twisted.web , посмотрите, как это можно сделать),

получить имя домена, субдомена, значения порта из этого?

теперь заголовок Host (cfr RFC раздел 14.23) содержит заголовоко.

1 голос
/ 10 августа 2010

На основании того, что вы, похоже, пытаетесь сделать, я думаю, что следующий путь будет наименьшим сопротивлением: http://twistedmatrix.com/documents/10.0.0/api/twisted.web.proxy.html

Это витой класс для построения HTTP-прокси.Это позволит вам перехватить запросы, посмотреть на пункт назначения и посмотреть на отправителя.Вы также можете просматривать все заголовки и содержимое, перемещаясь туда-сюда.Похоже, вы пытаетесь переписать класс HTTP Protocol и Proxy, который вам уже предоставлен.Надеюсь, это поможет.

...