Shane Spencer
2018-08-28 05:10:47 UTC
OK. I can't find hair nor hide of some past conversations with this.
I have a feeling I need to perform my http request in `prepare` and gain
early access to self.request.body in `prepare` with the intent of removing
it before moving on to the target method.
For now this is what I'm trying to hook up properly. Been all over github
looking for examples and I've found some pretty stellar ones.
@tornado.web.stream_request_body
class UpstreamHTTPHandler(tornado.web.RequestHandler):
def initialize(self, *args, **kwargs):
self.upstream_headers = tornado.httputil.HTTPHeaders()
self.upstream_body_queue = tornado.queues.Queue(maxsize=1)
self.request_body_queue = tornado.queues.Queue(maxsize=1)
self.request_body_buffer =
tempfile.SpooledTemporaryFile(mode='w+b', max_size=2e+6)
#self.request_body_read_bytes = 0 #use tell
self.request_body_content_length = None
self.request_body_cached = False
async def prepare(self, *args, **kwargs):
self.path_uri = self.path_kwargs.get('uri')
self.upstream_uri = f'{self.path_uri}?{self.request.query}'
if self.request.method in ('PATCH', 'POST', 'PUT'):
content_length = self.request.headers.get('Content-Length')
if not content_length:
raise tornado.web.HTTPError(405)
self.request_body_content_length = int(content_length, 10)
async def body_producer(self, write):
async for chunk in self.request_body_queue:
if chunk is QUEUE_FINISH:
break
print('sssss', time.time(), len(chunk),
self.request_body_buffer.tell(), self.request_body_queue.qsize())
write(chunk)
print('fin')
async def data_received(self, chunk):
print('rrrrr', time.time(), len(chunk),
self.request_body_buffer.tell(), self.request_body_queue.qsize())
if self.request_body_content_length is None:
return
await self.request_body_queue.put(chunk)
self.request_body_buffer.write(chunk)
if self.request_body_buffer.tell() >=
self.request_body_content_length:
self.request_body_queue.put(QUEUE_FINISH)
#self.request_body_buffer.rollover()
def header_callback(self, header_line):
print(textwrap.indent(header_line.strip(), 'header_callback: '))
if header_line.startswith("HTTP/"):
self.upstream_headers.clear()
return
if header_line == "\r\n":
return
self.upstream_headers.parse_line(header_line)
print(textwrap.indent(pprint.pformat(dict(self.upstream_headers)),
'all_headers: '))
def streaming_callback(self, chunk):
print(textwrap.indent(chunk.decode('utf-8'), 'streaming_callback:
'))
self.upstream_body_queue.put(chunk)
async def run(self,*args, **kwargs):
response = await tornado.httpclient.AsyncHTTPClient(
max_buffer_size=100000000,
max_body_size=1e+10, #10 GB
).fetch(
self.upstream_uri,
raise_error=False,
follow_redirects=True,
method=self.request.method,
allow_nonstandard_methods=True,
request_timeout=10000,
body_producer=self.body_producer,
header_callback=self.header_callback,
streaming_callback=self.streaming_callback,
)
print('response', response, self.request_body_buffer.name,
self.request_body_buffer._rolled)
self.finish()
self.request_body_buffer.close()
get = run
post = run
<https://about.me/ShaneSpencer?promo=email_sig&utm_source=product&utm_medium=email_sig&utm_campaign=gmail_api&utm_content=thumb>
Shane Spencer
about.me/ShaneSpencer
<https://about.me/ShaneSpencer?promo=email_sig&utm_source=product&utm_medium=email_sig&utm_campaign=gmail_api&utm_content=thumb>
I have a feeling I need to perform my http request in `prepare` and gain
early access to self.request.body in `prepare` with the intent of removing
it before moving on to the target method.
For now this is what I'm trying to hook up properly. Been all over github
looking for examples and I've found some pretty stellar ones.
@tornado.web.stream_request_body
class UpstreamHTTPHandler(tornado.web.RequestHandler):
def initialize(self, *args, **kwargs):
self.upstream_headers = tornado.httputil.HTTPHeaders()
self.upstream_body_queue = tornado.queues.Queue(maxsize=1)
self.request_body_queue = tornado.queues.Queue(maxsize=1)
self.request_body_buffer =
tempfile.SpooledTemporaryFile(mode='w+b', max_size=2e+6)
#self.request_body_read_bytes = 0 #use tell
self.request_body_content_length = None
self.request_body_cached = False
async def prepare(self, *args, **kwargs):
self.path_uri = self.path_kwargs.get('uri')
self.upstream_uri = f'{self.path_uri}?{self.request.query}'
if self.request.method in ('PATCH', 'POST', 'PUT'):
content_length = self.request.headers.get('Content-Length')
if not content_length:
raise tornado.web.HTTPError(405)
self.request_body_content_length = int(content_length, 10)
async def body_producer(self, write):
async for chunk in self.request_body_queue:
if chunk is QUEUE_FINISH:
break
print('sssss', time.time(), len(chunk),
self.request_body_buffer.tell(), self.request_body_queue.qsize())
write(chunk)
print('fin')
async def data_received(self, chunk):
print('rrrrr', time.time(), len(chunk),
self.request_body_buffer.tell(), self.request_body_queue.qsize())
if self.request_body_content_length is None:
return
await self.request_body_queue.put(chunk)
self.request_body_buffer.write(chunk)
if self.request_body_buffer.tell() >=
self.request_body_content_length:
self.request_body_queue.put(QUEUE_FINISH)
#self.request_body_buffer.rollover()
def header_callback(self, header_line):
print(textwrap.indent(header_line.strip(), 'header_callback: '))
if header_line.startswith("HTTP/"):
self.upstream_headers.clear()
return
if header_line == "\r\n":
return
self.upstream_headers.parse_line(header_line)
print(textwrap.indent(pprint.pformat(dict(self.upstream_headers)),
'all_headers: '))
def streaming_callback(self, chunk):
print(textwrap.indent(chunk.decode('utf-8'), 'streaming_callback:
'))
self.upstream_body_queue.put(chunk)
async def run(self,*args, **kwargs):
response = await tornado.httpclient.AsyncHTTPClient(
max_buffer_size=100000000,
max_body_size=1e+10, #10 GB
).fetch(
self.upstream_uri,
raise_error=False,
follow_redirects=True,
method=self.request.method,
allow_nonstandard_methods=True,
request_timeout=10000,
body_producer=self.body_producer,
header_callback=self.header_callback,
streaming_callback=self.streaming_callback,
)
print('response', response, self.request_body_buffer.name,
self.request_body_buffer._rolled)
self.finish()
self.request_body_buffer.close()
get = run
post = run
<https://about.me/ShaneSpencer?promo=email_sig&utm_source=product&utm_medium=email_sig&utm_campaign=gmail_api&utm_content=thumb>
Shane Spencer
about.me/ShaneSpencer
<https://about.me/ShaneSpencer?promo=email_sig&utm_source=product&utm_medium=email_sig&utm_campaign=gmail_api&utm_content=thumb>
--
You received this message because you are subscribed to the Google Groups "Tornado Web Server" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python-tornado+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
You received this message because you are subscribed to the Google Groups "Tornado Web Server" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python-tornado+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.