enhanced httpd

This commit is contained in:
2012-02-08 12:59:59 +00:00
parent 17d05bb1e0
commit 517107ab79
15 changed files with 1473 additions and 706 deletions

View File

@ -106,46 +106,41 @@ qse_env_char_t** qse_env_getarr (
qse_env_t* env
);
int qse_env_insertw (
qse_env_t* env,
/**
* The qse_env_insertwcs() function adds a new environment variable
* @a name with the @a value. If the @a value is #QSE_NULL, it takes
* the actual value from the system environment
*
* @return 0 on success, -1 on failure
*/
int qse_env_insertwcs (
qse_env_t* env,
const qse_wchar_t* name,
const qse_wchar_t* value
);
int qse_env_insertm (
qse_env_t* env,
int qse_env_insertmbs (
qse_env_t* env,
const qse_mchar_t* name,
const qse_mchar_t* value
);
int qse_env_deletew (
qse_env_t* env,
int qse_env_deletewcs (
qse_env_t* env,
const qse_wchar_t* name
);
int qse_env_deletem (
qse_env_t* env,
const qse_mchar_t* name
);
int qse_env_insertsysw (
qse_env_t* env,
const qse_wchar_t* name
);
int qse_env_insertsysm (
qse_env_t* env,
int qse_env_deletembs (
qse_env_t* env,
const qse_mchar_t* name
);
#if defined(QSE_CHAR_IS_WCHAR)
# define qse_env_insert(env,name,value) qse_env_insertw(env,name,value)
# define qse_env_delete(env,name) qse_env_deletew(env,name)
# define qse_env_insertsys(env,name) qse_env_insertsysw(env,name)
# define qse_env_insert(env,name,value) qse_env_insertwcs(env,name,value)
# define qse_env_delete(env,name) qse_env_deletewcs(env,name)
#else
# define qse_env_insert(env,name,value) qse_env_insertm(env,name,value)
# define qse_env_delete(env,name) qse_env_deletem(env,name)
# define qse_env_insertsys(env,name) qse_env_insertsysm(env,name)
# define qse_env_insert(env,name,value) qse_env_insertmbs(env,name,value)
# define qse_env_delete(env,name) qse_env_deletembs(env,name)
#endif
#ifdef __cplusplus

View File

@ -32,7 +32,8 @@ enum qse_htrd_errnum_t
QSE_HTRD_ENOMEM,
QSE_HTRD_EBADRE,
QSE_HTRD_EBADHDR,
QSE_HTRD_ERECBS
QSE_HTRD_ERECBS,
QSE_HTRD_ECONCB
};
typedef enum qse_htrd_errnum_t qse_htrd_errnum_t;
@ -45,7 +46,7 @@ enum qse_htrd_option_t
{
QSE_HTRD_SKIPEMPTYLINES = (1 << 0), /**< skip leading empty lines before the initial line */
QSE_HTRD_SKIPINITIALLINE = (1 << 1), /**< skip processing an initial line */
QSE_HTRD_HURRIED = (1 << 2), /**< trigger a callback also after headers without processing contents */
QSE_HTRD_PEEKONLY = (1 << 2), /**< trigger a peek callback after headers without processing contents */
QSE_HTRD_REQUEST = (1 << 3), /**< parse input as a request */
QSE_HTRD_RESPONSE = (1 << 4) /**< parse input as a response */
};
@ -56,9 +57,8 @@ typedef struct qse_htrd_recbs_t qse_htrd_recbs_t;
struct qse_htrd_recbs_t
{
int (*request) (qse_htrd_t* htrd, qse_htre_t* req);
int (*expect_continue) (qse_htrd_t* htrd, qse_htre_t* req);
int (*response) (qse_htrd_t* htrd, qse_htre_t* res);
int (*peek) (qse_htrd_t* htrd, qse_htre_t* re);
int (*handle) (qse_htrd_t* htrd, qse_htre_t* re);
};
struct qse_htrd_t

View File

@ -27,6 +27,20 @@
/* header and contents of request/response */
typedef struct qse_htre_t qse_htre_t;
enum qse_htre_flag_t
{
QSE_HTRE_DISCARDED = (1 << 0), /** content has been discarded */
QSE_HTRE_COMPLETED = (1 << 1) /** complete content has been seen */
};
typedef int (*qse_htre_concb_t) (
qse_htre_t* re,
const qse_mchar_t* ptr,
qse_size_t len,
void* ctx
);
struct qse_htre_t
{
qse_mmgr_t* mmgr;
@ -45,10 +59,7 @@ struct qse_htre_t
int content_length_set;
qse_size_t content_length;
int keepalive;
int expect_continue;
/* indicates if the content has been filled */
int hurried;
const qse_mchar_t* expect;
} attr;
/* header table */
@ -57,8 +68,12 @@ struct qse_htre_t
/* content octets */
qse_mbs_t content;
/* if set, the rest of the contents are discarded */
int discard;
/* content callback */
qse_htre_concb_t concb;
void* concb_ctx;
/* ORed of qse_htre_flag_t */
int flags;
};
#define qse_htre_getversion(re) (&((re)->version))
@ -111,13 +126,12 @@ struct qse_htre_t
#define qse_htre_setsmessagefromxstr(re,v) \
qse_htre_setstrfromxstr((re),qse_htre_getsmessage(re),(v))
/* NOTE: setcontent() doesn't execute concb. use this with care */
#define qse_htre_setcontentfromcstr(re,v) \
qse_htre_setstrfromcstr((re),qse_htre_getcontent(re),(v))
#define qse_htre_setcontentfromxstr(re,v) \
qse_htre_setstrfromxstr((re),qse_htre_getcontent(re),(v))
#define qse_htre_setdiscard(re,v) QSE_BLOCK((re)->discard = (v);)
typedef int (*qse_htre_header_walker_t) (
qse_htre_t* re,
const qse_mchar_t* key,
@ -165,6 +179,26 @@ int qse_htre_walkheaders (
void* ctx
);
int qse_htre_addcontent (
qse_htre_t* re,
const qse_mchar_t* ptr,
qse_size_t len
);
void qse_htre_unsetconcb (
qse_htre_t* re
);
void qse_htre_setconcb (
qse_htre_t* re,
qse_htre_concb_t concb,
void* ctx
);
const qse_mchar_t* qse_htre_getqmethodname (
qse_htre_t* re
);
#ifdef __cplusplus
}
#endif

View File

@ -51,9 +51,33 @@ enum qse_httpd_option_t
typedef struct qse_httpd_cbs_t qse_httpd_cbs_t;
struct qse_httpd_cbs_t
{
int (*handle_request) (
struct
{
/* action */
int (*recv) (qse_httpd_t* httpd,
qse_httpd_client_t* client,
qse_mchar_t* buf, qse_size_t bufsize);
int (*send) (qse_httpd_t* httpd,
qse_httpd_client_t* client,
const qse_mchar_t* buf, qse_size_t bufsize);
int (*sendfile) (qse_httpd_t* httpd,
qse_httpd_client_t* client,
qse_ubi_t handle, qse_foff_t* offset, qse_size_t count);
/* event notification */
int (*accepted) (
qse_httpd_t* httpd,
qse_httpd_client_t* client); /* optional */
void (*closed) (
qse_httpd_t* httpd,
qse_httpd_client_t* client); /* optional */
} client;
int (*peek_request) (
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_htre_t* req);
int (*handle_expect_continue) (
int (*handle_request) (
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_htre_t* req);
const qse_mchar_t* (*getmimetype) (qse_httpd_t* httpd, const qse_mchar_t* path);
@ -80,6 +104,15 @@ typedef int (*qse_httpd_task_main_t) (
qse_httpd_task_t* task
);
enum qse_httpd_task_trigger_mask_t
{
QSE_HTTPD_TASK_TRIGGER_READ = (1 << 0),
QSE_HTTPD_TASK_TRIGGER_WRITE = (1 << 1),
QSE_HTTPD_TASK_TRIGGER_READABLE = (1 << 2),
QSE_HTTPD_TASK_TRIGGER_WRITABLE = (1 << 3)
};
struct qse_httpd_task_t
{
/* you must not call another entask functions from within
@ -89,7 +122,8 @@ struct qse_httpd_task_t
qse_httpd_task_fini_t fini;
qse_httpd_task_main_t main;
qse_ubi_t trigger;
int trigger_mask;
qse_ubi_t trigger[2];
void* ctx;
};
@ -143,8 +177,9 @@ void qse_httpd_setcbs (
* specify the number of output threads.
*/
int qse_httpd_loop (
qse_httpd_t* httpd,
int threaded
qse_httpd_t* httpd,
qse_httpd_cbs_t* cbs,
int threaded
);
/**
@ -161,11 +196,16 @@ int qse_httpd_addlistener (
);
void qse_httpd_markclientbad (
void qse_httpd_markbadclient (
qse_httpd_t* httpd,
qse_httpd_client_t* client
);
void qse_httpd_discardcontent (
qse_httpd_t* httpd,
qse_htre_t* req
);
#define qse_httpd_gettaskxtn(httpd,task) ((void*)(task+1))
qse_httpd_task_t* qse_httpd_entask (
@ -235,6 +275,13 @@ qse_httpd_task_t* qse_httpd_entaskerror (
const qse_htre_t* req
);
qse_httpd_task_t* qse_httpd_entaskcontinue (
qse_httpd_t* httpd,
qse_httpd_client_t* client,
const qse_httpd_task_t* task,
const qse_htre_t* req
);
qse_httpd_task_t* qse_httpd_entaskpath (
qse_httpd_t* httpd,
qse_httpd_client_t* client,