Commit 6cf29651 authored by valenok's avatar valenok

added debug trace in mg_start. restored stderr duping in spawn_process()

parent 546bec33
...@@ -8,7 +8,7 @@ import mongoose ...@@ -8,7 +8,7 @@ import mongoose
import sys import sys
# Handle /show and /form URIs. # Handle /show and /form URIs.
def uri_handler(conn, info): def EventHandler(conn, info):
if info.uri == '/show': if info.uri == '/show':
conn.printf('%s', 'HTTP/1.0 200 OK\r\n') conn.printf('%s', 'HTTP/1.0 200 OK\r\n')
conn.printf('%s', 'Content-Type: text/plain\r\n\r\n') conn.printf('%s', 'Content-Type: text/plain\r\n\r\n')
...@@ -46,12 +46,13 @@ def error_handler(conn, info): ...@@ -46,12 +46,13 @@ def error_handler(conn, info):
# Create mongoose object, and register '/foo' URI handler # Create mongoose object, and register '/foo' URI handler
# List of options may be specified in the contructor # List of options may be specified in the contructor
server = mongoose.Mongoose(document_root='/tmp', server = mongoose.Mongoose(EventHandler,
new_request_handler=uri_handler, document_root='/tmp',
http_error_handler=error_handler,
listening_ports='8080') listening_ports='8080')
print 'Starting Mongoose server, press enter to quit' print ('Mongoose started on port %s, press enter to quit'
% server.get_option('listening_ports'))
sys.stdin.read(1) sys.stdin.read(1)
# Deleting server object stops all serving threads # Deleting server object stops all serving threads
......
...@@ -26,14 +26,10 @@ This module provides python binding for the Mongoose web server. ...@@ -26,14 +26,10 @@ This module provides python binding for the Mongoose web server.
There are two classes defined: There are two classes defined:
Connection: - wraps all functions that accept struct mg_connection pointer Connection: - wraps all functions that accept struct mg_connection pointer
as first argument as first argument.
Mongoose: wraps all functions that accept struct mg_context pointer as Mongoose: wraps all functions that accept struct mg_context pointer as
first argument. All valid option names, settable via mg_set_option(), first argument.
are settable/gettable as the attributes of the Mongoose object.
In addition to those, two attributes are available:
'version': string, contains server version
'options': array of all known options.
Creating Mongoose object automatically starts server, deleting object Creating Mongoose object automatically starts server, deleting object
automatically stops it. There is no need to call mg_start() or mg_stop(). automatically stops it. There is no need to call mg_start() or mg_stop().
...@@ -44,12 +40,6 @@ import ctypes ...@@ -44,12 +40,6 @@ import ctypes
import os import os
MG_ERROR = 0
MG_SUCCESS = 1
MG_NOT_FOUND = 2
MG_BUFFER_TOO_SMALL = 3
class mg_header(ctypes.Structure): class mg_header(ctypes.Structure):
"""A wrapper for struct mg_header.""" """A wrapper for struct mg_header."""
_fields_ = [ _fields_ = [
...@@ -76,47 +66,18 @@ class mg_request_info(ctypes.Structure): ...@@ -76,47 +66,18 @@ class mg_request_info(ctypes.Structure):
] ]
mg_callback_t = ctypes.CFUNCTYPE(ctypes.c_int, mg_callback_t = ctypes.CFUNCTYPE(ctypes.c_void_p,
ctypes.c_voidp, ctypes.c_void_p,
ctypes.POINTER(mg_request_info)) ctypes.POINTER(mg_request_info))
class mg_config(ctypes.Structure):
"""A wrapper for struct mg_config."""
_fields_ = [
('document_root', ctypes.c_char_p),
('index_files', ctypes.c_char_p),
('ssl_certificate', ctypes.c_char_p),
('listening_ports', ctypes.c_char_p),
('cgi_extensions', ctypes.c_char_p),
('cgi_interpreter', ctypes.c_char_p),
('cgi_environment', ctypes.c_char_p),
('ssi_extensions', ctypes.c_char_p),
('auth_domain', ctypes.c_char_p),
('protect', ctypes.c_char_p),
('global_passwords_file', ctypes.c_char_p),
('put_delete_passwords_file', ctypes.c_char_p),
('access_log_file', ctypes.c_char_p),
('error_log_file', ctypes.c_char_p),
('acl', ctypes.c_char_p),
('uid', ctypes.c_char_p),
('mime_types', ctypes.c_char_p),
('enable_directory_listing', ctypes.c_char_p),
('num_threads', ctypes.c_char_p),
('new_request_handler', mg_callback_t),
('http_error_handler', mg_callback_t),
('event_log_handler', mg_callback_t),
('ssl_password_handler', mg_callback_t),
]
class Connection(object): class Connection(object):
"""A wrapper class for all functions that take """A wrapper class for all functions that take
struct mg_connection * as the first argument.""" struct mg_connection * as the first argument."""
def __init__(self, mongoose, connection): def __init__(self, mongoose, connection):
self.m = mongoose self.m = mongoose
self.conn = ctypes.c_voidp(connection) self.conn = ctypes.c_void_p(connection)
def get_header(self, name): def get_header(self, name):
val = self.m.dll.mg_get_header(self.conn, name) val = self.m.dll.mg_get_header(self.conn, name)
...@@ -128,10 +89,6 @@ class Connection(object): ...@@ -128,10 +89,6 @@ class Connection(object):
n = self.m.dll.mg_get_var(data, size, name, buf, size) n = self.m.dll.mg_get_var(data, size, name, buf, size)
return n == MG_SUCCESS and buf or None 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, name) or None
def printf(self, fmt, *args): def printf(self, fmt, *args):
val = self.m.dll.mg_printf(self.conn, fmt, *args) val = self.m.dll.mg_printf(self.conn, fmt, *args)
return ctypes.c_int(val).value return ctypes.c_int(val).value
...@@ -150,7 +107,7 @@ class Connection(object): ...@@ -150,7 +107,7 @@ class Connection(object):
class Mongoose(object): class Mongoose(object):
"""A wrapper class for Mongoose shared library.""" """A wrapper class for Mongoose shared library."""
def __init__(self, **kwargs): def __init__(self, callback, **kwargs):
dll_extension = os.name == 'nt' and 'dll' or 'so' dll_extension = os.name == 'nt' and 'dll' or 'so'
self.dll = ctypes.CDLL('_mongoose.%s' % dll_extension) self.dll = ctypes.CDLL('_mongoose.%s' % dll_extension)
...@@ -161,48 +118,35 @@ class Mongoose(object): ...@@ -161,48 +118,35 @@ class Mongoose(object):
self.dll.mg_printf.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_header.restype = ctypes.c_char_p
self.dll.mg_get_var.restype = ctypes.c_int 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.dll.mg_get_cookie.restype = ctypes.c_int
self.dll.mg_get_option.restype = ctypes.c_char_p
self.callbacks = [] if callback:
self.config = mg_config(num_threads='5',
enable_directory_listing='yes',
listening_ports='8080',
document_root='.',
auth_domain='mydomain.com')
for key, value in kwargs.iteritems():
if key in ('new_request_handler',
'http_error_handler',
'event_log_handler',
'ssl_password_handler'):
cb = self.MakeHandler(value)
setattr(self.config, key, cb)
else:
setattr(self.config, key, str(value))
self.ctx = self.dll.mg_start(ctypes.byref(self.config))
def __del__(self):
"""Destructor, stop Mongoose instance."""
self.dll.mg_stop(ctypes.c_void_p(self.ctx))
def MakeHandler(self, python_func):
"""Return C callback from given Python callback."""
# Create a closure that will be called by the shared library. # Create a closure that will be called by the shared library.
def func(connection, request_info): def func(connection, request_info):
# Wrap connection pointer into the connection # Wrap connection pointer into the connection
# object and call Python callback # object and call Python callback
conn = Connection(self, connection) conn = Connection(self, connection)
status = python_func(conn, request_info.contents) if python_func(conn, request_info.contents):
return status == MG_SUCCESS and MG_SUCCESS or MG_ERROR return 'non-null-pointer'
else:
return ctypes.c_void_p(0)
# Convert the closure into C callable object # Convert the closure into C callable object
c_func = mg_callback_t(func) self.callback = mg_callback_t(func)
c_func.restype = ctypes.c_int self.callback.restype = ctypes.c_void_p
else:
self.callback = ctypes.c_void_p(0)
# Store created callback in the list, so it is kept alive args = [y for x in kwargs.items() for y in x] + [None]
# during context lifetime. Otherwise, python can garbage options = (ctypes.c_char_p * len(args))(*args)
# collect it, and C code will crash trying to call it.
self.callbacks.append(c_func) # self.ctx = self.dll.mg_start(self.callback, options)
self.ctx = self.dll.mg_start(ctypes.c_void_p(0), options)
def __del__(self):
"""Destructor, stop Mongoose instance."""
self.dll.mg_stop(ctypes.c_void_p(self.ctx))
return c_func def get_option(self, name):
return self.dll.mg_get_option(self.ctx, name)
...@@ -1176,7 +1176,7 @@ static pid_t spawn_process(struct mg_connection *conn, const char *prog, ...@@ -1176,7 +1176,7 @@ static pid_t spawn_process(struct mg_connection *conn, const char *prog,
} else if (dup2(fd_stdout, 1) == -1) { } else if (dup2(fd_stdout, 1) == -1) {
cry(conn, "%s: dup2(%d, 1): %s", __func__, fd_stdout, strerror(ERRNO)); cry(conn, "%s: dup2(%d, 1): %s", __func__, fd_stdout, strerror(ERRNO));
} else { } else {
//(void) dup2(fd_stdout, 2); (void) dup2(fd_stdout, 2);
(void) close(fd_stdin); (void) close(fd_stdin);
(void) close(fd_stdout); (void) close(fd_stdout);
...@@ -3827,6 +3827,7 @@ struct mg_context *mg_start(mg_callback_t user_callback, const char **options) { ...@@ -3827,6 +3827,7 @@ struct mg_context *mg_start(mg_callback_t user_callback, const char **options) {
free(ctx->config[i]); free(ctx->config[i]);
} }
ctx->config[i] = mg_strdup(value); ctx->config[i] = mg_strdup(value);
DEBUG_TRACE(("[%s] -> [%s]", name, value));
} }
if (!verify_document_root(ctx)) { if (!verify_document_root(ctx)) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment