【问题标题】:How to construct a webob.Request or a WSGI 'environ' dict from raw HTTP request byte stream?如何从原始 HTTP 请求字节流构造 webob.Request 或 WSGI 'environ' dict?
【发布时间】:2009-06-18 00:00:43
【问题描述】:

假设我有一个字节流,其中包含以下内容:

POST /mum/ble?q=huh 内容长度:18 内容类型:应用程序/json;字符集="utf-8" 主机:本地主机:80 [“做”,“重新”,“我”]

有没有办法从中生成 WSGI 风格的“环境”字典?

希望我忽略了一个简单的答案,它与相反的操作一样容易实现。 考虑:

>>> import json
>>> from webob import Request
>>> r = Request.blank('/mum/ble?q=huh')
>>> r.method = 'POST'
>>> r.content_type = 'application/json'
>>> r.charset = 'utf-8'
>>> r.body = json.dumps(['do', 're', 'mi'])
>>> print str(r) # Request's __str__ method gives raw HTTP bytes back!
POST /mum/ble?q=huh
内容长度:18
内容类型:应用程序/json;字符集="utf-8"
主机:本地主机:80

[“做”,“重新”,“我”]

【问题讨论】:

    标签: python wsgi webob


    【解决方案1】:

    为此目的重用 Python 的标准库代码有点棘手(它不是为这样重用而设计的!-),但应该是可行的,例如:

    import cStringIO
    from wsgiref import simple_server, util
    
    input_string = """POST /mum/ble?q=huh HTTP/1.0
    Content-Length: 18
    Content-Type: application/json; charset="utf-8"
    Host: localhost:80
    
    ["do", "re", "mi"]
    """
    
    class FakeHandler(simple_server.WSGIRequestHandler):
        def __init__(self, rfile):
            self.rfile = rfile
            self.wfile = cStringIO.StringIO() # for error msgs
            self.server = self
            self.base_environ = {}
            self.client_address = ['?', 80]
            self.raw_requestline = self.rfile.readline()
            self.parse_request()
    
        def getenv(self):
            env = self.get_environ()
            util.setup_testing_defaults(env)
            env['wsgi.input'] = self.rfile
            return env
    
    handler = FakeHandler(rfile=cStringIO.StringIO(input_string))
    wsgi_env = handler.getenv()
    
    print wsgi_env
    

    基本上,我们需要对请求处理程序进行子类化,以伪造通常由服务器为其执行的构造过程(rfilewfile 从套接字构建到客户端,等等)。我认为这还不是很完整,但应该很接近,我希望它会有所帮助!

    请注意,我还修复了您的示例 HTTP 请求:在原始请求行的末尾没有 HTTP/1.0 或 1.1,POST 被认为是格式错误的,并导致异常并导致错误消息handler.wfile.

    【讨论】:

    • Alex,谢谢,它像宣传的那样工作。而且我还通过 webob.Request.__str__ 再次往返该 dict 并获得了预期的结果(减去 HTTP 版本,由于某种原因 Request 类不会产生)。
    • 我怀疑“self.server = self”会导致内存泄漏。因此,在执行“handler = FakeHandler(...)”之后,执行“del handler.server”是一个好主意。
    • @offby1,引用循环(self.server = self 确实创建了)不是内存泄漏,因为 Python 确实为引用循环提供了垃圾收集;如果您可以明智地打破循环,那将通过避免gc 传递来加快速度。
    猜你喜欢
    • 2014-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-24
    • 1970-01-01
    • 2021-12-23
    相关资源
    最近更新 更多