From 75dea7aa4326039ce9aea296f8a310572022964b Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Thu, 30 Oct 2014 05:53:35 +0000 Subject: [PATCH] added preloop and postloop hooks into qse_httpd_ecb_t. added qse_httpd_custom_t for customized event dispatching allowed dns and urs services to be disabled programatically added qse_httpd_addhnd() and qse_httpd_delhnd() for customized event dispatching --- qse/cmd/http/httpd.c | 3 +- qse/include/qse/http/httpd.h | 78 +++++++++++++++++++++++++++++++----- qse/lib/http/httpd-std.c | 1 + qse/lib/http/httpd.c | 61 +++++++++++++++++++++++----- qse/lib/http/httpd.h | 1 + 5 files changed, 125 insertions(+), 19 deletions(-) diff --git a/qse/cmd/http/httpd.c b/qse/cmd/http/httpd.c index 9e7c8d51..bbcaa633 100644 --- a/qse/cmd/http/httpd.c +++ b/qse/cmd/http/httpd.c @@ -30,7 +30,6 @@ #elif defined(__DOS__) # include # include /* watt-32 */ -# include #else # include # include @@ -2797,6 +2796,8 @@ int qse_main (int argc, qse_achar_t* argv[]) ret = -1; goto oops; } + + /*trace2com_init (1, 38400);*/ #endif #if defined(HAVE_SSL) diff --git a/qse/include/qse/http/httpd.h b/qse/include/qse/http/httpd.h index bde8977b..d9eb1459 100644 --- a/qse/include/qse/http/httpd.h +++ b/qse/include/qse/http/httpd.h @@ -37,6 +37,7 @@ typedef struct qse_httpd_server_t qse_httpd_server_t; typedef struct qse_httpd_client_t qse_httpd_client_t; typedef struct qse_httpd_dns_t qse_httpd_dns_t; typedef struct qse_httpd_urs_t qse_httpd_urs_t; +typedef struct qse_httpd_custom_t qse_httpd_custom_t; typedef qse_intptr_t qse_httpd_hnd_t; @@ -179,13 +180,14 @@ enum qse_httpd_mux_mask_t QSE_HTTPD_MUX_READ = (1 << 0), QSE_HTTPD_MUX_WRITE = (1 << 1) }; +typedef enum qse_httpd_mux_mask_t qse_httpd_mux_mask_t; typedef int (*qse_httpd_muxcb_t) ( - qse_httpd_t* httpd, - void* mux, - qse_httpd_hnd_t handle, - int mask, /* ORed of qse_httpd_mux_mask_t */ - void* cbarg + qse_httpd_t* httpd, + void* mux, + qse_httpd_hnd_t handle, + int mask, /**> bitwise-ORed of #qse_httpd_mux_mask_t */ + void* cbarg ); typedef struct qse_httpd_dirent_t qse_httpd_dirent_t; @@ -302,6 +304,10 @@ typedef int (*qse_httpd_urs_prerewrite_t) ( qse_mchar_t** url ); +/** + * The qse_httpd_scb_t type defines a structure to store + * user-defined callback functions for system interfacing. + */ typedef struct qse_httpd_scb_t qse_httpd_scb_t; struct qse_httpd_scb_t { @@ -423,8 +429,13 @@ struct qse_httpd_scb_t struct { + /** opens the name resolution service. set this to #QSE_NULL to + * disable the service */ int (*open) (qse_httpd_t* httpd, qse_httpd_dns_t* dns); + + /** stops the name resolution service. */ void (*close) (qse_httpd_t* httpd, qse_httpd_dns_t* dns); + int (*recv) (qse_httpd_t* httpd, qse_httpd_dns_t* dns, qse_httpd_hnd_t handle); int (*send) (qse_httpd_t* httpd, qse_httpd_dns_t* dns, const qse_mchar_t* name, qse_httpd_resolve_t resol, @@ -435,8 +446,13 @@ struct qse_httpd_scb_t struct { + /** opens the url rewriting service. set this to #QSE_NULL to disable + * the service */ qse_httpd_urs_open_t open; + + /** stops the url rewriting service. */ qse_httpd_urs_close_t close; + qse_httpd_urs_recv_t recv; qse_httpd_urs_send_t send; qse_httpd_urs_prerewrite_t prerewrite; @@ -574,7 +590,8 @@ enum qse_httpd_mate_type_t QSE_HTTPD_SERVER, QSE_HTTPD_CLIENT, QSE_HTTPD_DNS, - QSE_HTTPD_URS + QSE_HTTPD_URS, + QSE_HTTPD_CUSTOM }; typedef enum qse_httpd_mate_type_t qse_httpd_mate_type_t; @@ -589,6 +606,15 @@ struct qse_httpd_mate_t QSE_HTTPD_MATE_HDR; }; +struct qse_httpd_custom_t +{ + /* == PRIVATE == */ + QSE_HTTPD_MATE_HDR; + + /* == PUBLIC == */ + int (*dispatch) (qse_httpd_t* httpd, void* mux, qse_httpd_hnd_t handle, int mask); +}; + struct qse_httpd_client_t { /* == PRIVATE == */ @@ -901,6 +927,14 @@ typedef void (*qse_httpd_ecb_close_t) ( qse_httpd_t* httpd /**< httpd */ ); +typedef void (*qse_httpd_ecb_preloop_t) ( + qse_httpd_t* httpd /**< httpd */ +); + +typedef void (*qse_httpd_ecb_postloop_t) ( + qse_httpd_t* httpd /**< httpd */ +); + /** * The qse_httpd_ecb_t type defines an event callback set. * You can register a callback function set with @@ -915,12 +949,25 @@ struct qse_httpd_ecb_t */ qse_httpd_ecb_close_t close; + /** + * called by qse_httpd_loop() before the actual event looping begins. + * you may call qse_httpd_stop() to prevent the loop from beginning. + * qse_httpd_stop() takes effect all all preloop hooks are executed. + * the postloop hooks are still executed when qse_httpd_stop() + * stops the start of the loop. + */ + qse_httpd_ecb_preloop_t preloop; + + /** + * called by qse_httpd_loop() after the actual event looping ends. + */ + qse_httpd_ecb_postloop_t postloop; + + /* internal use only. don't touch this field */ qse_httpd_ecb_t* next; }; - - #ifdef __cplusplus extern "C" { #endif @@ -1035,6 +1082,20 @@ QSE_EXPORT qse_httpd_server_t* qse_httpd_getprevserver ( qse_httpd_server_t* server ); + +QSE_EXPORT int qse_httpd_addhnd ( + qse_httpd_t* httpd, + qse_httpd_hnd_t handle, + int mask, /**> bitwise-ORed of #qse_httpd_mux_mask_t */ + qse_httpd_custom_t* mate +); + +QSE_EXPORT int qse_httpd_delhnd ( + qse_httpd_t* httpd, + qse_httpd_hnd_t handle +); + + QSE_EXPORT void qse_httpd_discardcontent ( qse_httpd_t* httpd, qse_htre_t* req @@ -1045,7 +1106,6 @@ QSE_EXPORT void qse_httpd_completecontent ( qse_htre_t* req ); - /** * The qse_httpd_setname() function changes the string * to be used as the value for the server header. diff --git a/qse/lib/http/httpd-std.c b/qse/lib/http/httpd-std.c index 32ca6cc5..0097c7de 100644 --- a/qse/lib/http/httpd-std.c +++ b/qse/lib/http/httpd-std.c @@ -730,6 +730,7 @@ qse_httpd_t* qse_httpd_openstdwithmmgr (qse_mmgr_t* mmgr, qse_size_t xtnsize) if (httpd == QSE_NULL) goto oops; xtn = (httpd_xtn_t*)qse_httpd_getxtn (httpd); + QSE_MEMSET (xtn, 0, QSE_SIZEOF(httpd_xtn_t*)); #if defined(USE_LTDL) /* lt_dlinit() can be called more than once and diff --git a/qse/lib/http/httpd.c b/qse/lib/http/httpd.c index 4e685f40..32c8a61c 100644 --- a/qse/lib/http/httpd.c +++ b/qse/lib/http/httpd.c @@ -581,6 +581,8 @@ static void purge_client (qse_httpd_t* httpd, qse_httpd_client_t* client) else httpd->client.list.head = next; if (next) next->prev = prev; else httpd->client.list.tail = prev; + + httpd->client.list.count--; } static void purge_client_list (qse_httpd_t* httpd) @@ -643,11 +645,10 @@ static int accept_client ( if (httpd->opt.scb.server.accept (httpd, server, &clibuf) <= -1) { -#if 0 -/* TODO: proper logging */ -qse_char_t tmp[128]; -qse_nwadtostr (&server->dope.nwad, tmp, QSE_COUNTOF(tmp), QSE_NWADTOSTR_ALL); -qse_printf (QSE_T("failed to accept from server [%s] [%d]\n"), tmp, server->handle); +#if 1 +qse_mchar_t tmp[128]; +qse_nwadtombs (&server->dope.nwad, tmp, QSE_COUNTOF(tmp), QSE_NWADTOSTR_ALL); +printf ("failed to accept from server [%s] [%d]\n", tmp, server->handle); #endif return -1; @@ -694,6 +695,7 @@ qse_printf (QSE_T("failed to accept from server [%s] [%d]\n"), tmp, server->hand httpd->client.list.head = client; httpd->client.list.tail = client; } + httpd->client.list.count++; if (httpd->opt.trait & QSE_HTTPD_LOGACT) { @@ -898,6 +900,20 @@ qse_httpd_server_t* qse_httpd_getprevserver (qse_httpd_t* httpd, qse_httpd_serve return server->prev; } + +int qse_httpd_addhnd (qse_httpd_t* httpd, qse_httpd_hnd_t handle, int mask, qse_httpd_custom_t* mate) +{ + /* qse_httpd_loop() opens the multiplexer. you can call this function from + * preloop/postloop hooks only. but calling it from postloop hooks is + * useless. */ + return httpd->opt.scb.mux.addhnd (httpd, httpd->mux, handle, QSE_HTTPD_MUX_READ, mate); +} + +int qse_httpd_delhnd (qse_httpd_t* httpd, qse_httpd_hnd_t handle) +{ + return httpd->opt.scb.mux.delhnd (httpd, httpd->mux, handle); +} + /* ----------------------------------------------------------------------- */ static int activate_dns (qse_httpd_t* httpd) @@ -905,6 +921,13 @@ static int activate_dns (qse_httpd_t* httpd) int i; QSE_MEMSET (&httpd->dns, 0, QSE_SIZEOF(httpd->dns)); + + if (!httpd->opt.scb.dns.open) + { + httpd->errnum = QSE_HTTPD_ENOIMPL; + return -1; + } + if (httpd->opt.scb.dns.open (httpd, &httpd->dns) <= -1) return -1; httpd->dns.type = QSE_HTTPD_DNS; @@ -949,6 +972,13 @@ static int activate_urs (qse_httpd_t* httpd) int i; QSE_MEMSET (&httpd->urs, 0, QSE_SIZEOF(httpd->urs)); + + if (!httpd->opt.scb.urs.open) + { + httpd->errnum = QSE_HTTPD_ENOIMPL; + return -1; + } + if (httpd->opt.scb.urs.open (httpd, &httpd->urs) <= -1) return -1; httpd->urs.type = QSE_HTTPD_URS; @@ -1598,8 +1628,7 @@ qse_httpd_task_t* qse_httpd_entask ( return (qse_httpd_task_t*)new_task; } -static int dispatch_mux ( - qse_httpd_t* httpd, void* mux, qse_httpd_hnd_t handle, int mask, void* cbarg) +static int dispatch_mux (qse_httpd_t* httpd, void* mux, qse_httpd_hnd_t handle, int mask, void* cbarg) { switch (((qse_httpd_mate_t*)cbarg)->type) { @@ -1614,6 +1643,9 @@ static int dispatch_mux ( case QSE_HTTPD_URS: return perform_urs (httpd, mux, handle, mask, cbarg); + + case QSE_HTTPD_CUSTOM: + return ((qse_httpd_custom_t*)cbarg)->dispatch (httpd, mux, handle, mask); } httpd->errnum = QSE_HTTPD_EINTERN; @@ -1624,6 +1656,7 @@ int qse_httpd_loop (qse_httpd_t* httpd) { int xret, count; qse_ntime_t tmout; + qse_httpd_ecb_t* ecb; QSE_ASSERTX (httpd->server.list.head != QSE_NULL, "Add listeners before calling qse_httpd_loop()"); @@ -1695,13 +1728,18 @@ printf ("no active servers...\n"); return -1; } -printf ("entering loop... ...\n"); - xret = 0; + /* call preloop hooks */ + for (ecb = httpd->ecb; ecb; ecb = ecb->next) + { + if (ecb->preloop) ecb->preloop (httpd); + } + xret = 0; while (!httpd->stopreq) { if (qse_tmr_gettmout (httpd->tmr, QSE_NULL, &tmout) <= -1) tmout = httpd->opt.tmout; count = httpd->opt.scb.mux.poll (httpd, httpd->mux, &tmout); +printf ("polled ... ...%d client count = %d tmout = %d.%d\n", (int)count, (int)httpd->client.list.count, (int)tmout.sec, (int)tmout.nsec); if (count <= -1) { printf ("mux errorr ... ...\n"); @@ -1722,6 +1760,11 @@ printf ("mux errorr ... ...\n"); } } + for (ecb = httpd->ecb; ecb; ecb = ecb->next) + { + if (ecb->postloop) ecb->postloop (httpd); + } + purge_client_list (httpd); deactivate_servers (httpd); diff --git a/qse/lib/http/httpd.h b/qse/lib/http/httpd.h index 90affdba..ba829245 100644 --- a/qse/lib/http/httpd.h +++ b/qse/lib/http/httpd.h @@ -61,6 +61,7 @@ struct qse_httpd_t { qse_httpd_client_t* head; qse_httpd_client_t* tail; + qse_size_t count; } list; struct