2010-08-07 2 views
3

Я изучаю сетевое программирование с использованием скрученного 10 в python. В нижеприведенном коде есть способ обнаружения HTTP-запроса при получении данных? также получить имя домена, поддомен, значения порта из этого? Отбросить его, если это не http-данные?Как определить HTTP-запрос в python + twisted?

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() 

ответ

3

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

Вызывается всякий раз, когда данные принимаются.

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

Параметры

data 

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

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

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

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

После того, как вы красиво отформатирована/разобранный ответ (рассмотреть изучение twisted.web's sources так увидеть один способ, которым это может быть сделано),

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

теперь Host заголовок (ЧФР the RFC раздел 14,23) является один, содержащий эту информацию.

+0

спасибо alex за ответ. Ваш ответ очень полезен для новичков, таких как me.I получить к нему :) –

+0

не проблема, я на самом деле потратил много времени, борясь с аналогичной проблемой и получить витой HTTP-прокси работает сам. Как только вы это выясните, он очень гладко. – themaestro

1

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

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