From ef04ce988723b1a3a1cff458465f37b5c126bf82 Mon Sep 17 00:00:00 2001 From: valenok Date: Sat, 28 Aug 2010 00:32:00 +0100 Subject: [PATCH] enhance python binding - add example for GET/POST, and use mg_read() there. --- bindings/python/example.py | 43 ++++++++++++++++++++++++------------- bindings/python/mongoose.py | 34 +++++++++++++++++++++-------- 2 files changed, 53 insertions(+), 24 deletions(-) diff --git a/bindings/python/example.py b/bindings/python/example.py index 37d8f939..ecd26967 100644 --- a/bindings/python/example.py +++ b/bindings/python/example.py @@ -7,24 +7,37 @@ import mongoose import sys -# This function is a "/foo" URI handler: it will be called each time -# HTTP request to http://this_machine:8080/foo made. -# It displays some request information. +# Handle /show and /form URIs. def uri_handler(conn, info): - if info.uri != '/foo': + if info.uri == '/show': + conn.printf('%s', 'HTTP/1.0 200 OK\r\n') + conn.printf('%s', 'Content-Type: text/plain\r\n\r\n') + conn.printf('%s %s\n', info.request_method, info.uri) + if info.request_method == 'POST': + content_len = conn.get_header('Content-Length') + post_data = conn.read(int(content_len)) + my_var = conn.get_var(post_data, 'my_var') + else: + my_var = conn.get_qsvar(info, 'my_var') + conn.printf('my_var: %s\n', my_var or '') + conn.printf('HEADERS: \n') + for header in info.http_headers[:info.num_headers]: + conn.printf(' %s: %s\n', header.name, header.value) + return mongoose.MG_SUCCESS + elif info.uri == '/form': + conn.write('HTTP/1.0 200 OK\r\n' + 'Content-Type: text/html\r\n\r\n' + 'Use GET: link' + '
' + 'Use POST: type text and submit: ' + '' + '' + '
') + return mongoose.MG_SUCCESS + else: return mongoose.MG_ERROR - conn.printf('%s', 'HTTP/1.0 200 OK\r\n') - conn.printf('%s', 'Content-Type: text/plain\r\n\r\n') - conn.printf('%s %s\n', info.request_method, info.uri) - conn.printf('my_var: %s\n', - conn.get_qsvar(info, 'my_var') or '') - conn.printf('HEADERS: \n') - for header in info.http_headers[:info.num_headers]: - conn.printf(' %s: %s\n', header.name, header.value) - return mongoose.MG_SUCCESS -# This function is 404 error handler: it is called each time requested -# document is not found by the server. +# Invoked each time HTTP error is triggered. def error_handler(conn, info): conn.printf('%s', 'HTTP/1.0 200 OK\r\n') conn.printf('%s', 'Content-Type: text/plain\r\n\r\n') diff --git a/bindings/python/mongoose.py b/bindings/python/mongoose.py index c8aeffcd..b8f3cfd7 100644 --- a/bindings/python/mongoose.py +++ b/bindings/python/mongoose.py @@ -122,16 +122,15 @@ class Connection(object): val = self.m.dll.mg_get_header(self.conn, name) return ctypes.c_char_p(val).value - def get_var(self, buf, buflen, name): - size = 1024 - value = ctypes.create_string_buffer(size) - self.m.dll.mg_get_var.restype = ctypes.c_int - result = self.m.dll.mg_get_var(buf, buflen, name, value, size) - return result == MG_ERROR and None or value + def get_var(self, data, name): + size = len(data) + buf = ctypes.create_string_buffer(size) + n = self.m.dll.mg_get_var(data, size, name, buf, size) + return n == MG_SUCCESS and buf or None def get_qsvar(self, request_info, name): qs = request_info.query_string - return qs and self.get_var(qs, len(qs), name) or None + return qs and self.get_var(qs, name) or None def printf(self, fmt, *args): val = self.m.dll.mg_printf(self.conn, fmt, *args) @@ -140,6 +139,12 @@ class Connection(object): def write(self, data): val = self.m.dll.mg_write(self.conn, data, len(data)) return ctypes.c_int(val).value + + def read(self, size): + buf = ctypes.create_string_buffer(size) + n = self.m.dll.mg_read(self.conn, buf, size) + print size, buf, n + return n <= 0 and None or buf[:n] class Mongoose(object): @@ -148,6 +153,17 @@ class Mongoose(object): def __init__(self, **kwargs): dll_extension = os.name == 'nt' and 'dll' or 'so' self.dll = ctypes.CDLL('_mongoose.%s' % dll_extension) + + self.dll.mg_start.restype = ctypes.c_void_p + self.dll.mg_modify_passwords_file.restype = ctypes.c_int + self.dll.mg_read.restype = ctypes.c_int + self.dll.mg_write.restype = ctypes.c_int + self.dll.mg_printf.restype = ctypes.c_int + self.dll.mg_get_header.restype = ctypes.c_char_p + self.dll.mg_get_var.restype = ctypes.c_int + self.dll.mg_get_qsvar.restype = ctypes.c_int + self.dll.mg_get_cookie.restype = ctypes.c_int + self.callbacks = [] self.config = mg_config(num_threads='5', enable_directory_listing='yes', @@ -163,7 +179,6 @@ class Mongoose(object): setattr(self.config, key, cb) else: setattr(self.config, key, str(value)) - self.dll.mg_start.restype = ctypes.c_void_p self.ctx = self.dll.mg_start(ctypes.byref(self.config)) def __del__(self): @@ -178,7 +193,8 @@ class Mongoose(object): # Wrap connection pointer into the connection # object and call Python callback conn = Connection(self, connection) - return python_func(conn, request_info.contents) + status = python_func(conn, request_info.contents) + return status == MG_SUCCESS and MG_SUCCESS or MG_ERROR # Convert the closure into C callable object c_func = mg_callback_t(func)