Example #1
0
def yyyy(user_data_id, unset_event=False):
    ud_id =  ctypes.cast(user_data_id, ctypes.POINTER(ctypes.c_long))
    #print "DEL %i (%r)" % (ud_id.contents.value, ud_map.keys() )
    if not ud_id:
        return None, None
    user_data = ud_map[ud_id.contents.value]
    
    # use the same environ
    #return user_data['callback'](*user_data['args'], **user_data['kwargs'])
    environ = user_data['response'].environ
    environ['PATH_INFO'] = user_data['callback_url']
    environ['response_prev'] = user_data['response']
    
    
    del ud_map[ud_id.contents.value]
    if unset_event:
        libevent.event_del(user_data['byref(event)'])
        if 'buf' in environ and environ['buf']:
            libevent.evbuffer_free(environ['buf'])
            del environ['buf']

    del user_data['byref(event)']
    del user_data['byref(id)']
    del user_data['id']
    del user_data['event']
    return user_data, environ
Example #2
0
def root_handler(req, environ, event_type=0):
    t0 = time.time()
    # force type conversion. I have no idea why it's needed but it is.
    req = ctypes.cast(req, req_type)
    
    if not environ:
        environ = request_to_environ(req)
        first_request = True
    else:
        first_request = False
        
    environ['event_type'] = event_type
    try:
        status_code, status_reason, response_headers, data, response = django_handler( environ.copy() )
    except Exception: # all exceptions...
        traceback.print_exc(file=sys.stdout)
        status_code, status_reason, response_headers, data, response = \
            500 , 'INTERNAL SERVER ERROR', (), '<h1>500 internal server error</h1>', object()

    if hasattr(response, 'continuation') and response.continuation:
        continuation = True
    else:
        continuation = False

    if first_request: # only on first request
        for key, value in response_headers:
            libevent.evhttp_add_header(req.contents.output_headers, str(key), str(value))

    
    content_length = 0
    content_type = ''
    
    # first_request, and we don't continue and string -> straight response
    if event_type == EVENT_CLOSED:
        if data:
            print "fuckoff, event is closed and you want to return data"
    elif first_request and isinstance(data, str) and not continuation:
        # libevent is broken, it's not sending content-length for http1.0
        libevent.evhttp_add_header(req.contents.output_headers, 'Content-Length', str(len(data)))
        
        assert(first_request)
        assert(isinstance(data, str))
        buf=libevent.evbuffer_new()
        libevent.evbuffer_add(buf, data, len(data))
        libevent.evhttp_send_reply(req, status_code, status_reason, buf)
        libevent.evbuffer_free(buf)
        content_length = len(data)
        content_type = ''
        
    # else: chunked:
    else: #force chunked
        if isinstance(data, str):   # yep, we need list
            data = [data]
        
        assert(isinstance(data, list))
        
        # first reqiest: open the chunkinkg mode
        if first_request:
            buf=libevent.evbuffer_new()
            libevent.evhttp_send_reply_start(req, status_code, status_reason)
        else:
            buf = environ['buf']
            buf = ctypes.cast(buf, buf_type)
        
        content_type = 'chunk'

        # for chunk in chunks...
        for data_chunk in data:
            if not data:
                continue
            assert(isinstance(data_chunk, str))
            libevent.evbuffer_add(buf,data_chunk, len(data_chunk))
            libevent.evhttp_send_reply_chunk(req, buf)
            content_length += len(data_chunk)
        
        # don't continue the answer in the future -> close
        if not continuation:
            libevent.evhttp_send_reply_end(req)
            libevent.evbuffer_free(buf)
            if 'buf' in environ:
                del environ['buf']
        else:
            # don't close the connection and save the request object and environ
            response.environ = environ
            response.http_request = req
            environ['buf'] = buf

    if getattr(response, 'schedule', None) and response.schedule and event_type != EVENT_CLOSED:
        libevent.evhttp_connection_set_closecb(req.contents.evcon, close_callback_ptr, response.schedule)
        response.schedule = None

    t1 = time.time()
    print '''%(date)s %(host)s "%(method)s %(url)s %(http)s" %(status_code)i %(content_length)i %(content_type)s %(continuation)s  (%(time).3fms)''' % {
        'date':datetime.datetime.now().strftime("[%Y-%m-%d %H:%M:%S]"),
        'method':environ['REQUEST_METHOD'],
        'url': environ['PATH_INFO'] + '?' + environ['QUERY_STRING'],
        'http': environ['SERVER_PROTOCOL'],
        'status_code': status_code,
        'content_length': content_length,
        'content_type': content_type,
        'continuation': '...<' if event_type==EVENT_CLOSED else '' if not continuation else '>...' if first_request else '...',
        'host': '%s:%i' % (environ['REMOTE_HOST'], environ['REMOTE_PORT']),
        'time': (t1-t0) * 1000, # in miliseconds
        }
    
    return 1