开发者

Failed to get the HTTP POST request body using Twisted

I was trying to get the HTTP POST request body by using t.p.basic.LineReceiver but failed. My code is listed below:

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

But when I was doing HTTP POST 开发者_JAVA百科request to that machine at port 80, only the HTTP request headers were printed out. Sample output:

  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: ''

So the connection was not closed here but the POST body was not received either.

I have tested the network condition by running sudo nc -l 80 and it did print out the HTTP POST request body.

So, how could I get the HTTP POST request body using Twisted? Thank you very much.


I suspect you didn't see the request body printed out because it didn't contain any newlines or end with a newline. So it got into the parse buffer of your PrintPostBody instance and sat there forever, waiting for a newline to indicate that a full line had been received. LineReceiver won't call the lineReceived callback until a full line is received.

Instead, you can let Twisted Web do this parsing for you:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜