view example.py @ 59:b0f802c4fafc

Fixed what (I think) are channel memory management bugs.
author Atul Varma <varmaa@toolness.com>
date Tue, 28 Apr 2009 22:07:52 -0700
parents 6fc400fb8b0b
children
line wrap: on
line source

from cosocket import *
import channels

def _make_http_response(msg, mimetype = 'text/plain'):
    return ('HTTP/1.1 200 OK\r\n' +
            'Keep-Alive: timeout=99, max=99\r\n' +
            'Connection: Keep-Alive\r\n' +
            'Content-Length: %d\r\n' % len(msg) +
            'Content-Type: %s\r\n\r\n' % mimetype +
            msg)

def _make_chunk(msg, mimetype = 'text/plain'):
    return ('Content-Length: %d\r\n' % len(msg) +
            'Content-Type: text/plain\r\n\r\n' +
            msg +
            '\r\n--chunk\r\n')

num_messages = 0

strands = 0

def example_http_server_coroutine(addr):
    global strands
    strands += 1
    my_id = strands
    while 1:
        try:
            yield _process_one_request(addr)
        except GeneratorExit:
            #print "%d: closing!" % my_id
            raise
        #print "%d: processed one request!" % my_id

def _process_one_request(addr):
    global num_messages
    request = yield until_received(terminator = '\r\n\r\n')
    request = request.splitlines()
    request_line = request[0]
    request_headers = request[1:]
    req_parts = request_line.split()
    if req_parts[1] == '/listen':
        yield until_sent('HTTP/1.1 200 OK\r\n' +
                         'Content-Type: multipart/x-mixed-replace; ' +
                         'boundary="chunk"\r\n\r\n--chunk\r\n')
        while 1:
            ip, num = yield channels.until_message_received('global')
            msg = 'Got message %d from %s.' % (num, ip)
            yield until_sent(_make_chunk(msg))
    elif req_parts[1] == '/send':
        num_messages += 1
        yield channels.until_message_sent('global',
                                          (addr[0], num_messages))
        yield until_sent(_make_http_response('sent.'))
    else:
        yield until_sent(_make_http_response(
                # TODO: This is bad since we're reading the file
                # synchronously.
                open('example.html', 'r').read(),
                'text/html'
                ))

def _example_nested_coroutine():
    chunk = yield until_received(bytes = 20)
    print 'first chunk : %s' % repr(chunk)
    chunk = yield until_received(bytes = 20)
    print 'second chunk: %s' % repr(chunk)

def example_http_client_coroutine(addr):
    yield until_sent('GET / HTTP/1.1\r\n\r\n')
    response_headers = yield until_received(terminator = '\r\n\r\n')
    yield _example_nested_coroutine()
    chunk = yield until_received(bytes = 20)
    print 'third chunk : %s' % repr(chunk)

if __name__ == '__main__':
    server = CoroutineSocketServer(('127.0.0.1', 8071),
                                   example_http_server_coroutine)
    try:
        client = CoroutineSocketClient(('www.google.com', 80),
                                       example_http_client_coroutine)
    except:
        import traceback
        traceback.print_exc()
    server.run()