Skip to content

Instantly share code, notes, and snippets.

@bdarnell
Created February 17, 2014 19:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bdarnell/9056988 to your computer and use it in GitHub Desktop.
Save bdarnell/9056988 to your computer and use it in GitHub Desktop.
Sketches of potential HTTPServer callback interfaces
from tornado.concurrent import Future
from tornado import gen
from somewhere import parse_headers
class HTTPReader(object):
def __init__(self, stream):
self.stream = stream
self.header_future = Future()
self.chunk_future = None
self.read_ready = Future()
self.body_done = False
self.start()
def read_headers(self):
return self.header_future
def more_body(self):
# This could probably be better as a toro.Queue instead of a pair of
# Futures.
self.chunk_future = Future()
self.read_ready.set_result(None)
return not self.body_done
def read_body_chunk(self):
return self.chunk_future
@gen.coroutine
def start(self):
header_data = yield self.stream.read_until('\r\n\r\n')
first_line, headers = parse_headers(header_data)
self.header_future.set_result((first_line, headers))
content_len = int(headers['Content-Length'])
while content_len:
yield self.read_ready
self.read_ready = Future()
chunk = yield self.stream.read_some(content_len)
content_len -= len(chunk)
self.chunk_future.set_result(chunk)
self.body_done = True
from tornado import gen
from somewhere import parse_headers
class HTTPReader(object):
def __init__(self, stream):
self.stream = stream
self.content_len = None
@gen.coroutine
def read_headers(self):
header_data = yield self.stream.read_until('\r\n\r\n')
first_line, headers = parse_headers(header_data)
self.content_len = int(headers['Content-Length'])
raise gen.Return((first_line, headers))
def more_body(self):
return bool(self.content_len)
@gen.coroutine
def read_body_chunk(self):
chunk = yield self.stream.read_some(self.content_len)
self.content_len -= len(chunk)
raise gen.Return(chunk)
from tornado.concurrent import is_future, Future
from tornado import gen
from somewhere import parse_headers
def make_future(obj):
if is_future(obj):
return obj
future = Future()
future.set_result(obj)
return future
class HTTPReaderDelegate(object):
def headers_received(self, first_line, headers):
pass
def data_received(self, data):
pass
def eof_received(self):
pass
@gen.coroutine
def read_http(stream, delegate):
header_data = yield stream.read_until('\r\n\r\n')
first_line, headers = parse_headers(header_data)
yield make_future(delegate.headers_received(first_line, headers))
content_len = int(headers['Content-Length'])
while content_len:
chunk = yield stream.read_some(content_len)
content_len -= len(chunk)
yield make_future(delegate.data_received(chunk))
yield make_future(delegate.eof_received())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment