Skip to content

Instantly share code, notes, and snippets.

@coopernurse
Created April 18, 2011 20:11
Show Gist options
  • Save coopernurse/926066 to your computer and use it in GitHub Desktop.
Save coopernurse/926066 to your computer and use it in GitHub Desktop.
# in diesel's http.py HttpServer class:
# read_body is new
def __init__(self, method, url, version, remote_addr=None, read_body=True):
self.read_body = read_body
def __call__(self, addr):
'''Since an instance of HttpServer is passed to the Service
class (with appropriate request_handler established during
initialization), this __call__ method is what's actually
invoked by diesel.
This is our generator, this is our protocol handler.
It does protocol work, then calls the request_handler,
looking for HttpClose if necessary.
'''
while True:
chunks = []
# ...
# lines snipped from example..
# ...
req.body = None
if self.read_body:
req.read_body()
if not self.request_handler(req):
break
# in HttpRequest:
# moved from HttpServer
BODY_CHUNKED, BODY_CL, BODY_NONE = range(3)
# moved from HttpServer
def check_for_http_body(self):
... # use self.headers - already set
# mostly lifted from HttpServer
def read_body(self):
more_mode = self.check_for_http_body()
if more_mode is self.BODY_NONE:
req.body = None
elif more_mode is self.BODY_CL:
req.body = receive(int(self.headers.get_one('Content-Length')))
elif more_mode is self.BODY_CHUNKED:
req.body = handle_chunks(self.headers)
# new method that would allow callers to stream the body as it's read
def stream_body(self, chunk_size=2048, chunk_callback):
# not sure if this is anti-coroutine-ish..
# but callers who wanted to process the body as a stream would provide
# a callback - pseudo code:
total_bytes = int(self.headers.get_one('Content-Length'))
bytes_read = 0
while bytes_read < total_bytes:
c = read_chunk(chunk_size) # ?? somehow ask diesel for x bytes and block here
bytes_read += len(c)
chunk_callback(c, bytes_read, total_bytes)
# in Aspen's cli.py
# don't read body automatically
app.add_service(Service(http.HttpServer(website, read_body=False), port))
# in Aspen's website.py - Website class
def __call__(self, diesel_request):
# TODO: hook parsing body. do something smart with multipart posts
# ideally let users hook their own callbacks
#
# call existing code:
request = Request.from_diesel(diesel_request) # too big to fail :-/
response = self.handle(request)
return response._to_diesel(diesel_request) # sends bits, returns bool
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment