Ok,twisted get body of POST request
Esto debería ser simple, ya que las personas lo hacen todo el tiempo. Quiero que el cuerpo de una solicitud POST envíe un retorcido Agent
. Esto se crea con un retorcido FileBodyProducer
. En el lado del servidor, obtengo un objeto request
para mi método render_POST
.
¿Cómo recupero el cuerpo?
servidor:
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()
Los únicos documentos que puedo encontrar para configurar el lado del consumidor leave something to be desired. Principalmente, ¿cómo puede un consumidor utilizar el método write(data)
para recibir los resultados?
¿Qué bit me falta para conectar estos dos componentes?
Para referencia futura, recomendaría no hacer request.write (fd.read()) con content-length establecido por os.stat(). St_size. Tuve un problema en el que recibía un IOError sin espacio en el dispositivo en request.write (fd.read()). Si tienes la memoria, te recomiendo que primero leas el archivo en un búfer, y luego en contenido-duración basado en len (buf). luego request.write (buf). –