attempting to add dynamic modules into httpd

This commit is contained in:
2014-09-03 16:57:33 +00:00
parent b54964ac85
commit 4b0f12a896
9 changed files with 534 additions and 166 deletions

View File

@ -18,6 +18,7 @@ libqsehttp_la_SOURCES = \
httpd-proxy.c \
httpd-std.c \
httpd-std-dns.h \
httpd-std-mod.h \
httpd-std-urs.h \
httpd-task.c \
httpd-text.c \

View File

@ -340,6 +340,7 @@ libqsehttp_la_SOURCES = \
httpd-proxy.c \
httpd-std.c \
httpd-std-dns.h \
httpd-std-mod.h \
httpd-std-urs.h \
httpd-task.c \
httpd-text.c \

View File

@ -2072,7 +2072,7 @@ static int task_main_proxy (
/* proxy->url_to_rewrite is the final rewritten URL by prerewrite().
* pass QSE_NULL as the second parameter to on_url_rewritten() to
* indicate that the original URL is not known */
on_url_rewritten (httpd, QSE_NULL, proxy->url_to_rewrite, task);
on_url_rewritten (httpd, QSE_NULL, (proxy->url_to_rewrite? proxy->url_to_rewrite: QSE_MT("")), task);
}
else
{

View File

@ -0,0 +1,216 @@
#if !defined(QSE_HTTPD_DEFAULT_MODPREFIX)
# if defined(_WIN32)
# define QSE_HTTPD_DEFAULT_MODPREFIX "qsehttpd-"
# elif defined(__OS2__)
# define QSE_HTTPD_DEFAULT_MODPREFIX "htd-"
# elif defined(__DOS__)
# define QSE_HTTPD_DEFAULT_MODPREFIX "htd-"
# else
# define QSE_HTTPD_DEFAULT_MODPREFIX "libqsehttpd-"
# endif
#endif
#if !defined(QSE_HTTPD_DEFAULT_MODPOSTFIX)
# define QSE_HTTPD_DEFAULT_MODPOSTFIX ""
#endif
static int mod_open (qse_httpd_t* httpd, qse_httpd_mod_t* mod)
{
#if defined(USE_LTDL)
void* h;
qse_mchar_t* modpath;
const qse_char_t* tmp[4];
int count;
count = 0;
if (spec->prefix) tmp[count++] = spec->prefix;
tmp[count++] = mod->name;
if (spec->postfix) tmp[count++] = spec->postfix;
tmp[count] = QSE_NULL;
#if defined(QSE_CHAR_IS_MCHAR)
modpath = qse_mbsadup (tmp, QSE_NULL, httpd->mmgr);
#else
modpath = qse_wcsatombsdup (tmp, QSE_NULL, httpd->mmgr);
#endif
if (!modpath)
{
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOMEM, QSE_NULL);
return -1;
}
h = lt_dlopenext (modpath);
QSE_MMGR_FREE (httpd->mmgr, modpath);
if (h == QSE_NULL) return -1;
mod->handle = h;
return 0;
#elif defined(_WIN32)
HMODULE h;
qse_char_t* modpath;
const qse_char_t* tmp[4];
int count;
count = 0;
if (spec->prefix) tmp[count++] = spec->prefix;
tmp[count++] = spec->name;
if (spec->postfix) tmp[count++] = spec->postfix;
tmp[count] = QSE_NULL;
modpath = qse_stradup (tmp, QSE_NULL, httpd->mmgr);
if (!modpath)
{
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOMEM, QSE_NULL);
return -1;
}
h = LoadLibrary (modpath);
QSE_MMGR_FREE (httpd->mmgr, modpath);
QSE_ASSERT (QSE_SIZEOF(h) <= QSE_SIZEOF(void*));
if (h == QSE_NULL) return -1;
mod->handle = h;
return 0;
#elif defined(__OS2__)
HMODULE h;
qse_mchar_t* modpath;
const qse_char_t* tmp[4];
int count;
char errbuf[CCHMAXPATH];
APIRET rc;
count = 0;
if (spec->prefix) tmp[count++] = spec->prefix;
tmp[count++] = spec->name;
if (spec->postfix) tmp[count++] = spec->postfix;
tmp[count] = QSE_NULL;
#if defined(QSE_CHAR_IS_MCHAR)
modpath = qse_mbsadup (tmp, QSE_NULL, httpd->mmgr);
#else
modpath = qse_wcsatombsdup (tmp, QSE_NULL, httpd->mmgr);
#endif
if (!modpath)
{
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOMEM, QSE_NULL);
return -1;
}
/* DosLoadModule() seems to have severe limitation on
* the file name it can load (max-8-letters.xxx) */
rc = DosLoadModule (errbuf, QSE_COUNTOF(errbuf) - 1, modpath, &h);
if (rc != NO_ERROR) h = QSE_NULL;
QSE_MMGR_FREE (httpd->mmgr, modpath);
QSE_ASSERT (QSE_SIZEOF(h) <= QSE_SIZEOF(void*));
if (h == QSE_NULL) return -1;
mod->handle = h;
return 0;
#elif defined(__DOS__)
/* the DOS code here is not generic enough. it's for a specific
* dos-extender only. the best is to enable QSE_ENABLE_STATIC_MODULE
* when building for DOS. */
void* h;
qse_mchar_t* modpath;
const qse_char_t* tmp[4];
int count;
count = 0;
if (spec->prefix) tmp[count++] = spec->prefix;
tmp[count++] = spec->name;
if (spec->postfix) tmp[count++] = spec->postfix;
tmp[count] = QSE_NULL;
#if defined(QSE_CHAR_IS_MCHAR)
modpath = qse_mbsadup (tmp, QSE_NULL, httpd->mmgr);
#else
modpath = qse_wcsatombsdup (tmp, QSE_NULL, httpd->mmgr);
#endif
if (!modpath)
{
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOMEM, QSE_NULL);
return 01;
}
h = LoadModule (modpath);
QSE_MMGR_FREE (httpd->mmgr, modpath);
QSE_ASSERT (QSE_SIZEOF(h) <= QSE_SIZEOF(void*));
if (h == QSE_NULL) return -1;
mod->handle = h;
return 0;
#else
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOIMPL);
return -1;
#endif
}
static void mod_close (qse_httpd_t* httpd, qse_httpd_mod_t* mod)
{
#if defined(USE_LTDL)
lt_dlclose (mod->handle);
#elif defined(_WIN32)
FreeLibrary ((HMODULE)mod->handle);
#elif defined(__OS2__)
DosFreeModule ((HMODULE)mod->handle);
#elif defined(__DOS__)
FreeModule (mod->handle);
#else
/* nothing to do */
#endif
}
static void* mod_symbol (qse_httpd_t* httpd, qse_httpd_mod_t* handle, const qse_char_t* name)
{
void* s;
qse_mchar_t* mname;
#if defined(QSE_CHAR_IS_MCHAR)
mname = name;
#else
mname = qse_wcstombsdup (name, QSE_NULL, httpd->mmgr);
if (!mname)
{
qse_httpd_seterrnum (httpd, QSE_HTTPD_ENOMEM);
return QSE_NULL;
}
#endif
#if defined(USE_LTDL)
s = lt_dlsym (mod->handle, mname);
#elif defined(_WIN32)
s = GetProcAddress ((HMODULE)mod->handle, mname);
#elif defined(__OS2__)
if (DosQueryProcAddr ((HMODULE)mod->handle, 0, mname, (PFN*)&s) != NO_ERROR) s = QSE_NULL;
#elif defined(__DOS__)
s = GetProcAddress (mod->handle, mname);
#else
s = QSE_NULL;
#endif
#if defined(QSE_CHAR_IS_MCHAR)
/* nothing to do */
#else
QSE_MMGR_FREE (httpd->mmgr, mname);
#endif
return s;
}

View File

@ -2294,6 +2294,7 @@ static qse_size_t hash_string (const qse_mchar_t *str)
return h;
}
#include "httpd-std-mod.h"
#include "httpd-std-dns.h"
#include "httpd-std-urs.h"
@ -2301,72 +2302,87 @@ static qse_size_t hash_string (const qse_mchar_t *str)
static qse_httpd_scb_t httpd_system_callbacks =
{
/* server */
{ server_open,
server_close,
server_accept
/* module */
{
mod_open,
mod_close,
mod_symbol
},
{ peer_open,
peer_close,
peer_connected,
peer_recv,
peer_send
/* server */
{
server_open,
server_close,
server_accept
},
{
peer_open,
peer_close,
peer_connected,
peer_recv,
peer_send
},
/* multiplexer */
{ mux_open,
mux_close,
mux_addhnd,
mux_delhnd,
mux_poll,
{
mux_open,
mux_close,
mux_addhnd,
mux_delhnd,
mux_poll,
mux_readable,
mux_writable
mux_readable,
mux_writable
},
/* file operation */
{ file_stat,
file_purge,
file_ropen,
file_wopen,
file_close,
file_read,
file_write
{
file_stat,
file_purge,
file_ropen,
file_wopen,
file_close,
file_read,
file_write
},
/* directory operation */
{ dir_stat,
dir_make,
dir_purge,
dir_open,
dir_close,
dir_read
{
dir_stat,
dir_make,
dir_purge,
dir_open,
dir_close,
dir_read
},
/* client connection */
{ client_close,
client_shutdown,
client_recv,
client_send,
client_sendfile,
client_accepted,
client_closed
{
client_close,
client_shutdown,
client_recv,
client_send,
client_sendfile,
client_accepted,
client_closed
},
/* dns */
{ dns_open,
dns_close,
dns_recv,
dns_send
{
dns_open,
dns_close,
dns_recv,
dns_send
},
/* urs */
{ urs_open,
urs_close,
urs_recv,
urs_send,
urs_prerewrite
{
urs_open,
urs_close,
urs_recv,
urs_send,
urs_prerewrite
}
};

View File

@ -37,6 +37,7 @@ struct htrd_xtn_t
static void free_server_list (qse_httpd_t* httpd);
static int perform_client_task (
qse_httpd_t* httpd, void* mux, qse_ubi_t handle, int mask, void* cbarg);
static void unload_all_modules (qse_httpd_t* httpd);
qse_http_version_t qse_http_v11 = { 1, 1 };
@ -89,6 +90,7 @@ void qse_httpd_fini (qse_httpd_t* httpd)
{
free_server_list (httpd);
qse_tmr_close (httpd->tmr);
unload_all_modules (httpd);
}
void qse_httpd_stop (qse_httpd_t* httpd)
@ -1844,3 +1846,61 @@ void qse_httpd_removetimerevent (qse_httpd_t* httpd, qse_tmr_index_t index)
{
qse_tmr_remove (httpd->tmr, index);
}
static void unload_all_modules (qse_httpd_t* httpd)
{
qse_httpd_mod_t* mod;
while (httpd->modlist)
{
mod = httpd->modlist;
httpd->modlist = mod->next;
/* call fini */
httpd->opt.scb.mod.close (httpd, mod);
qse_httpd_freemem (httpd, mod);
}
}
int qse_httpd_loadmod (qse_httpd_t* httpd, const qse_char_t* name)
{
qse_httpd_mod_t* mod;
qse_size_t name_len;
/* TODO: no singly linked list speed up */
name_len = qse_strlen(name);
mod = qse_httpd_allocmem (httpd, QSE_SIZEOF(*mod) + name_len + 1);
if (mod == QSE_NULL) return -1;
QSE_MEMSET (mod, 0, QSE_SIZEOF(*mod));
mod->name = mod + 1;
qse_strcpy (mod->name, name);
if (httpd->opt.scb.mod.open (httpd, mod) <= -1)
{
qse_httpd_freemem (httpd, mod);
return -1;
}
/* TODO: find init and execute it. if it fails, unload it. */
mod->next = httpd->modlist;
httpd->modlist = mod;
return 0;
}
qse_httpd_mod_t* qse_httpd_findmod (qse_httpd_t* httpd, const qse_char_t* name)
{
qse_httpd_mod_t* mod;
/* TODO: no sequential search. speed up */
for (mod = httpd->modlist; mod; mod = mod->next)
{
if (qse_strcmp (mod->name, name) == 0) return mod;
}
return QSE_NULL;
}

View File

@ -52,6 +52,8 @@ struct qse_httpd_t
qse_mchar_t sname[128]; /* server name for the server header */
qse_mchar_t gtbuf[10][64]; /* GMT time buffers */
qse_httpd_mod_t* modlist;
struct
{
struct