Не удалось получить тело HTTP-запроса POST с использованием Twisted - PullRequest
2 голосов
/ 19 декабря 2010

Я пытался получить тело запроса HTTP POST, используя t.p.basic.LineReceiver, но не смог. Мой код указан ниже:

from twisted.internet import reactor, protocol
from twisted.protocols import basic

class PrintPostBody(basic.LineReceiver):
    def __init__(self):
        self.line_no = 0

    def lineReceived(self, line):
        print '{0}: {1}'.format(str(self.line_no).rjust(3), repr(line))
        self.line_no += 1

    def connectionLost(self, reason):
        print "conn lost"

class PPBFactory(protocol.ServerFactory):
    protocol = PrintPostBody

def main():
    f = PPBFactory()
    reactor.listenTCP(80, f)
    reactor.run()


if __name__ == '__main__':
    main()

Но когда я выполнял HTTP-запрос POST к этому компьютеру через порт 80, распечатывались только заголовки HTTP-запроса. Пример вывода:

  0: 'POST / HTTP/1.0'
  1: 'Host: ###.##.##.##'
  2: 'Referer: http://#.#####.###/?ssid=0&from=0&bd_page_type=1&uid=wiaui_1292470548_2644&pu=sz%40176_229,sz%40176_208'
  3: 'Content-Length: 116'
  4: 'Origin: http://#.#####.###'
  5: 'Content-Type: application/x-www-form-urlencoded'
  6: 'Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5'
  7: 'User-Agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US) AppleWebKit/534.11 (KHTML, like Gecko) Chrome/9.0.565.0 Safari/534.11'
  8: 'Accept-Encoding: gzip,deflate,sdch'
  9: 'Accept-Language: en-US,en;q=0.8'
 10: 'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3'
 11: 'Via: 1.1 #####.###.###.##:8080 (squid/2.6.STABLE21)'
 12: 'X-Forwarded-For: ###.##.###.###'
 13: 'Cache-Control: max-age=0'
 14: 'Connection: keep-alive'
 15: ''

Таким образом, соединение здесь не было закрыто, но тело POST также не было получено.

Я проверил состояние сети, запустив sudo nc -l 80, и он распечатал тело запроса HTTP POST.

Итак, как я могу получить тело HTTP-запроса POST, используя Twisted? Большое спасибо.

1 Ответ

7 голосов
/ 19 декабря 2010

Я подозреваю, что вы не видели распечатанное тело запроса, потому что в нем не было ни новой строки, ни конца новой строки. Таким образом, он попал в буфер разбора вашего экземпляра PrintPostBody и сидел там вечно, ожидая новой строки, указывающей, что была получена полная строка. LineReceiver не будет вызывать обратный вызов lineReceived до тех пор, пока не будет получена полная строка.

Вместо этого вы можете позволить Twisted Web выполнить этот анализ для вас:

from twisted.web.server import Site  # Site is a server factory for HTTP
from twisted.web.resource import Resource
from twisted.internet import reactor

class PrintPostBody(Resource):  # Resources are what Site knows how to deal with
    isLeaf = True  # Disable child lookup

    def render_POST(self, request):  # Define a handler for POST requests
        print request.content.read()  # Get the request body from this file-like object
        return "" # Define the response body as empty

reactor.listenTCP(80, Site(PrintPostBody()))
reactor.run()
...