【问题标题】:Failed to get the HTTP POST request body using Twisted使用 Twisted 获取 HTTP POST 请求正文失败
【发布时间】:2011-05-27 18:26:32
【问题描述】:

我尝试使用 t.p.basic.LineReceiver 获取 HTTP POST 请求正文,但失败了。我的代码如下:

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

但是当我在端口 80 向那台机器发出 HTTP POST 请求时,只打印出 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 请求正文。

那么,如何使用 Twisted 获取 HTTP POST 请求正文? 非常感谢。

【问题讨论】:

    标签: python http twisted


    【解决方案1】:

    我怀疑您没有看到打印出的请求正文,因为它不包含任何换行符或以换行符结尾。所以它进入了你的 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()
    

    【讨论】:

    • 是的,你是对的。 HTTP POST 请求正文的末尾没有 CRLF,因此 LineReceiver 将永远等待。 +1 这个关键部分:) 然后我尝试使用 rawDataReceived() 代替它并且它起作用了。
    • “request.content.read()”不是阻止对扭曲性质的调用吗?
    • 也许,也许不是。对于大多数应用程序,本地磁盘足够快,可以在大多数情况下考虑非阻塞。如果您的应用程序不是这种情况,那么您可能希望避免这样做。
    猜你喜欢
    • 1970-01-01
    • 2018-05-10
    • 1970-01-01
    • 2015-08-18
    • 2015-05-07
    • 2015-02-18
    • 1970-01-01
    • 2014-04-17
    • 1970-01-01
    相关资源
    最近更新 更多