Come costruire un webob.Request o un dict 'environment' WSGI dal flusso di byte di richiesta HTTP non elaborato?
Domanda
Supponiamo di avere un flusso di byte con al suo interno:
POST /mum/ble?q=huh Content-Length: 18 Content-Type: application/json; charset="utf-8" Host: localhost:80 ["do", "re", "mi"]
C'è un modo per produrre un dict 'environment' in stile WSGI da esso?
Spero di aver trascurato una risposta semplice, ed è facile da raggiungere come l'operazione opposta. Prendere in considerazione:
>>> 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!
<*> Soluzione
Riutilizzare il codice della libreria standard di Python allo scopo è un po 'complicato (non è stato progettato per essere riutilizzato in questo modo! -), ma dovrebbe essere fattibile, ad esempio:
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
Fondamentalmente, dobbiamo sottoclassare il gestore delle richieste per falsificare il processo di costruzione che viene normalmente eseguito per esso dal server ( rfile
e wfile
creato dal socket al client e così via). Questo non è del tutto completo, penso, ma dovrebbe essere vicino e spero che si riveli utile!
Nota che ho anche corretto la tua richiesta HTTP di esempio: senza un HTTP / 1.0
o 1.1 alla fine della riga della richiesta non elaborata, un POST
è considerato malato -formato e causa un'eccezione e un messaggio di errore risultante su handler.wfile
.