Ok,twisted get body of POST request
Questo dovrebbe essere semplice, dal momento che le persone lo fanno tutto il tempo. Voglio ottenere il corpo di una richiesta POST inviato un contorto Agent
. Questo viene creato con un twistato FileBodyProducer
. Sul lato server, ottengo un oggetto request
per il mio metodo render_POST
.
Come recuperare il corpo?
server:
from twisted.web import server, resource
from twisted.internet import reactor
class Simple(resource.Resource):
isLeaf = True
def render_GET(self, request):
return "{0}".format(request.args.keys())
def render_POST(self, request):
return "{0}".format(request.data)
with open(request.args['filename'][0], 'rb') as fd:
fd.write(request.write())
site = server.Site(Simple())
reactor.listenTCP(8080, site)
reactor.run()
cliente:
from StringIO import StringIO
from twisted.internet import reactor
from twisted.web.client import Agent
from twisted.web.http_headers import Headers
from twisted.web.client import FileBodyProducer
from twisted.internet.defer import Deferred
from twisted.internet.protocol import Protocol
from pprint import pformat
class BeginningPrinter(Protocol):
def __init__(self, finished):
self.finished = finished
self.remaining = 1024 * 10
def dataReceived(self, bytes):
if self.remaining:
display = bytes[:self.remaining]
print 'Some data received:'
print display
self.remaining -= len(display)
def connectionLost(self, reason):
print 'Finished receiving body:', reason.getErrorMessage()
self.finished.callback(None)
agent = Agent(reactor)
body = FileBodyProducer(StringIO("hello, world"))
d = agent.request(
'POST',
'http://127.0.0.1:8080/',
Headers({'User-Agent': ['Twisted Web Client Example'],
'Content-Type': ['text/x-greeting']}),
body)
def cbRequest(response):
print 'Response version:', response.version
print 'Response code:', response.code
print 'Response phrase:', response.phrase
print 'Response headers:'
print pformat(list(response.headers.getAllRawHeaders()))
finished = Deferred()
response.deliverBody(BeginningPrinter(finished))
return finished
d.addCallback(cbRequest)
def cbShutdown(ignored):
reactor.stop()
d.addBoth(cbShutdown)
reactor.run()
Gli unici documenti che posso trovare per impostare il lato del consumatore leave something to be desired. In primo luogo, come può un consumatore utilizzare il metodo write(data)
per ricevere i risultati?
Quale bit mi manca per collegare questi due componenti insieme?
Per riferimento futuro, suggerirei di non eseguire request.write (fd.read()) con la lunghezza del contenuto impostata da os.stat(). St_size. Ho avuto un problema in cui stavo ottenendo un errore IOE non lasciato spazio sul dispositivo su request.write (fd.read()). Se si dispone della memoria, si consiglia di leggere prima il file in un buffer, quindi eseguire la lunghezza del contenuto in base a len (buf). quindi request.write (buf). –