Как создать webob.Request или WSGI «среду» из необработанного потока байтов HTTP-запроса? - PullRequest
3 голосов
/ 18 июня 2009

Предположим, у меня есть поток байтов со следующим:

POST /mum/ble?q=huh
Content-Length: 18
Content-Type: application/json; charset="utf-8"
Host: localhost:80

["do", "re", "mi"]

Есть ли способ создать из нее "среду" в стиле 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
Content-Length: 18
Content-Type: application/json; charset="utf-8"
Host: localhost:80

["do", "re", "mi"]

1 Ответ

5 голосов
/ 18 июня 2009

Повторное использование стандартного библиотечного кода 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

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

Обратите внимание, что я также исправил ваш пример HTTP-запроса: без HTTP/1.0 или 1.1 в конце строки необработанного запроса POST считается некорректным и вызывает исключение и получающееся сообщение об ошибке на handler.wfile.

...