moved directory list formatting to qse_httpd_rcb_t.
added some entask variants modified qse_mbsadup()/qse_mbsxadup()/qse_wcsadup(0/qse_wcsxadup() to return length
This commit is contained in:
parent
7940a758d0
commit
c6530a1c13
@ -994,11 +994,13 @@ qse_mchar_t* qse_mbsxdup2 (
|
||||
|
||||
qse_mchar_t* qse_mbsadup (
|
||||
const qse_mchar_t* str[],
|
||||
qse_size_t* len,
|
||||
qse_mmgr_t* mmgr
|
||||
);
|
||||
|
||||
qse_mchar_t* qse_mbsxadup (
|
||||
const qse_mcstr_t str[],
|
||||
qse_size_t* len,
|
||||
qse_mmgr_t* mmgr
|
||||
);
|
||||
|
||||
@ -1029,11 +1031,13 @@ qse_wchar_t* qse_wcsxdup2 (
|
||||
|
||||
qse_wchar_t* qse_wcsadup (
|
||||
const qse_wchar_t* str[],
|
||||
qse_size_t* len,
|
||||
qse_mmgr_t* mmgr
|
||||
);
|
||||
|
||||
qse_wchar_t* qse_wcsxadup (
|
||||
const qse_wcstr_t str[],
|
||||
qse_size_t* len,
|
||||
qse_mmgr_t* mmgr
|
||||
);
|
||||
|
||||
@ -1042,15 +1046,15 @@ qse_wchar_t* qse_wcsxadup (
|
||||
# define qse_strdup2(s1,s2,mmgr) qse_mbsdup2(s1,s2,mmgr)
|
||||
# define qse_strxdup(s,l,mmgr) qse_mbsxdup(s,l,mmgr)
|
||||
# define qse_strxdup2(s1,l1,s2,l2,mmgr) qse_mbsxdup(s1,l1,s2,l2,mmgr)
|
||||
# define qse_stradup(sa,mmgr) qse_mbsadup(sa,mmgr)
|
||||
# define qse_strxadup(sa,mmgr) qse_mbsxadup(sa,mmgr)
|
||||
# define qse_stradup(sa,len,mmgr) qse_mbsadup(sa,len,mmgr)
|
||||
# define qse_strxadup(sa,len,mmgr) qse_mbsxadup(sa,len,mmgr)
|
||||
#else
|
||||
# define qse_strdup(s,mmgr) qse_wcsdup(s,mmgr)
|
||||
# define qse_strdup2(s1,s2,mmgr) qse_wcsdup2(s1,s2,mmgr)
|
||||
# define qse_strxdup(s,l,mmgr) qse_wcsxdup(s,l,mmgr)
|
||||
# define qse_strxdup2(s1,l1,s2,l2,mmgr) qse_wcsxdup(s1,l1,s2,l2,mmgr)
|
||||
# define qse_stradup(sa,mmgr) qse_wcsadup(sa,mmgr)
|
||||
# define qse_strxadup(sa,mmgr) qse_wcsxadup(sa,mmgr)
|
||||
# define qse_stradup(sa,len,mmgr) qse_wcsadup(sa,len,mmgr)
|
||||
# define qse_strxadup(sa,len,mmgr) qse_wcsxadup(sa,len,mmgr)
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -163,6 +163,10 @@ int qse_comparehttpversions (
|
||||
const qse_http_version_t* v2
|
||||
);
|
||||
|
||||
const qse_mchar_t* qse_httpstatustombs (
|
||||
int code
|
||||
);
|
||||
|
||||
const qse_mchar_t* qse_httpmethodtombs (
|
||||
qse_http_method_t type
|
||||
);
|
||||
|
@ -46,6 +46,7 @@ enum qse_httpd_errnum_t
|
||||
QSE_HTTPD_EEXIST,
|
||||
QSE_HTTPD_EINTR,
|
||||
QSE_HTTPD_EAGAIN,
|
||||
QSE_HTTPD_ENOBUF,
|
||||
|
||||
QSE_HTTPD_EIOMUX,
|
||||
QSE_HTTPD_EDISCON, /* client disconnnected */
|
||||
@ -255,6 +256,14 @@ struct qse_httpd_rcb_t
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_htre_t* req);
|
||||
int (*handle_request) (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_htre_t* req);
|
||||
|
||||
int (*format_error) (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client,
|
||||
int code, qse_mchar_t* buf, int bufsz);
|
||||
int (*format_dir) (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client,
|
||||
const qse_mchar_t* qpath, const qse_httpd_dirent_t* dirent,
|
||||
qse_mchar_t* buf, int bufsz);
|
||||
};
|
||||
|
||||
typedef struct qse_httpd_task_t qse_httpd_task_t;
|
||||
@ -358,6 +367,7 @@ enum qse_httpd_rsrc_type_t
|
||||
QSE_HTTPD_RSRC_FILE,
|
||||
QSE_HTTPD_RSRC_PROXY,
|
||||
QSE_HTTPD_RSRC_RELOC,
|
||||
QSE_HTTPD_RSRC_REDIR,
|
||||
QSE_HTTPD_RSRC_TEXT
|
||||
};
|
||||
typedef enum qse_httpd_rsrc_type_t qse_httpd_rsrc_type_t;
|
||||
@ -384,7 +394,6 @@ struct qse_httpd_rsrc_t
|
||||
struct
|
||||
{
|
||||
const qse_mchar_t* path;
|
||||
const qse_mchar_t* css;
|
||||
} dir;
|
||||
|
||||
struct
|
||||
@ -403,11 +412,17 @@ struct qse_httpd_rsrc_t
|
||||
qse_nwad_t dst;
|
||||
qse_nwad_t src;
|
||||
} proxy;
|
||||
|
||||
struct
|
||||
{
|
||||
const qse_mchar_t* dst;
|
||||
} reloc;
|
||||
|
||||
struct
|
||||
{
|
||||
const qse_mchar_t* dst;
|
||||
} redir;
|
||||
|
||||
struct
|
||||
{
|
||||
const qse_mchar_t* ptr;
|
||||
@ -488,7 +503,7 @@ enum qse_httpd_server_xtn_cfg_idx_t
|
||||
|
||||
struct qse_httpd_server_xtn_t
|
||||
{
|
||||
qse_mxstr_t cfg[QSE_HTTPD_SERVER_XTN_CFG_MAX];
|
||||
qse_mchar_t* cfg[QSE_HTTPD_SERVER_XTN_CFG_MAX];
|
||||
qse_httpd_server_cbstd_t* cbstd;
|
||||
qse_httpd_server_cgistd_t* cgistd;
|
||||
qse_httpd_server_mimestd_t* mimestd;
|
||||
@ -699,12 +714,27 @@ qse_httpd_task_t* qse_httpd_entaskreloc (
|
||||
qse_htre_t* req
|
||||
);
|
||||
|
||||
qse_httpd_task_t* qse_httpd_entaskredir (
|
||||
qse_httpd_t* httpd,
|
||||
qse_httpd_client_t* client,
|
||||
qse_httpd_task_t* pred,
|
||||
const qse_mchar_t* dst,
|
||||
qse_htre_t* req
|
||||
);
|
||||
|
||||
|
||||
qse_httpd_task_t* qse_httpd_entasknomod (
|
||||
qse_httpd_t* httpd,
|
||||
qse_httpd_client_t* client,
|
||||
qse_httpd_task_t* pred,
|
||||
qse_htre_t* req
|
||||
);
|
||||
|
||||
qse_httpd_task_t* qse_httpd_entaskdir (
|
||||
qse_httpd_t* httpd,
|
||||
qse_httpd_client_t* client,
|
||||
qse_httpd_task_t* pred,
|
||||
const qse_mchar_t* name,
|
||||
const qse_mchar_t* css,
|
||||
qse_htre_t* req
|
||||
);
|
||||
|
||||
|
@ -270,7 +270,7 @@ int qse_fs_move (
|
||||
arr[2] = qse_basename(oldpath);
|
||||
arr[3] = QSE_NULL;
|
||||
#if defined(QSE_CHAR_IS_MCHAR)
|
||||
fop.new_path2 = qse_stradup (arr, fs->mmgr);
|
||||
fop.new_path2 = qse_stradup (arr, QSE_NULL, fs->mmgr);
|
||||
#else
|
||||
fop.new_path2 = qse_wcsatombsdup (arr, fs->mmgr);
|
||||
#endif
|
||||
|
@ -199,7 +199,7 @@ int qse_fs_chdir (qse_fs_t* fs, const qse_char_t* name)
|
||||
|
||||
tmp_name[idx] = QSE_NULL;
|
||||
|
||||
fsname = qse_stradup (tmp_name, fs->mmgr);
|
||||
fsname = qse_stradup (tmp_name, QSE_NULL, fs->mmgr);
|
||||
if (fsname == QSE_NULL)
|
||||
{
|
||||
fs->errnum = QSE_FS_ENOMEM;
|
||||
@ -260,7 +260,7 @@ int qse_fs_chdir (qse_fs_t* fs, const qse_char_t* name)
|
||||
tmp_name[idx++] = name;
|
||||
tmp_name[idx] = QSE_NULL;
|
||||
|
||||
fsname = qse_stradup (tmp_name, fs->mmgr);
|
||||
fsname = qse_stradup (tmp_name, QSE_NULL, fs->mmgr);
|
||||
if (fsname == QSE_NULL)
|
||||
{
|
||||
fs->errnum = QSE_FS_ENOMEM;
|
||||
@ -453,7 +453,7 @@ qse_fs_ent_t* qse_fs_read (qse_fs_t* fs, int flags)
|
||||
tmp_name[1] = QSE_T("\\");
|
||||
tmp_name[2] = info->wfd.cFileName;
|
||||
tmp_name[3] = QSE_NULL;
|
||||
fname = qse_stradup (tmp_name, fs->mmgr);
|
||||
fname = qse_stradup (tmp_name, QSE_NULL, fs->mmgr);
|
||||
if (fname == QSE_NULL)
|
||||
{
|
||||
fs->errnum = QSE_FS_ENOMEM;
|
||||
@ -564,7 +564,7 @@ qse_fs_ent_t* qse_fs_read (qse_fs_t* fs, int flags)
|
||||
tmp_name[1] = QSE_MT("/");
|
||||
tmp_name[2] = ent->d_name;
|
||||
tmp_name[3] = QSE_NULL;
|
||||
mfname = qse_mbsadup (tmp_name, fs->mmgr);
|
||||
mfname = qse_mbsadup (tmp_name, QSE_NULL, fs->mmgr);
|
||||
if (mfname == QSE_NULL)
|
||||
{
|
||||
fs->errnum = QSE_FS_ENOMEM;
|
||||
|
@ -72,7 +72,7 @@ qse_mchar_t* qse_mbsxdup2 (
|
||||
return tmp;
|
||||
}
|
||||
|
||||
qse_mchar_t* qse_mbsadup (const qse_mchar_t* str[], qse_mmgr_t* mmgr)
|
||||
qse_mchar_t* qse_mbsadup (const qse_mchar_t* str[], qse_size_t* len, qse_mmgr_t* mmgr)
|
||||
{
|
||||
qse_mchar_t* buf, * ptr;
|
||||
qse_size_t i;
|
||||
@ -88,10 +88,11 @@ qse_mchar_t* qse_mbsadup (const qse_mchar_t* str[], qse_mmgr_t* mmgr)
|
||||
ptr = buf;
|
||||
for (i = 0; str[i]; i++) ptr += qse_mbscpy (ptr, str[i]);
|
||||
|
||||
if (len) *len = capa;
|
||||
return buf;
|
||||
}
|
||||
|
||||
qse_mchar_t* qse_mbsxadup (const qse_mcstr_t str[], qse_mmgr_t* mmgr)
|
||||
qse_mchar_t* qse_mbsxadup (const qse_mcstr_t str[], qse_size_t* len, qse_mmgr_t* mmgr)
|
||||
{
|
||||
qse_mchar_t* buf, * ptr;
|
||||
qse_size_t i;
|
||||
@ -107,6 +108,7 @@ qse_mchar_t* qse_mbsxadup (const qse_mcstr_t str[], qse_mmgr_t* mmgr)
|
||||
ptr = buf;
|
||||
for (i = 0; str[i].ptr; i++) ptr += qse_mbsncpy (ptr, str[i].ptr, str[i].len);
|
||||
|
||||
if (len) *len = capa;
|
||||
return buf;
|
||||
}
|
||||
|
||||
@ -165,7 +167,7 @@ qse_wchar_t* qse_wcsxdup2 (
|
||||
return tmp;
|
||||
}
|
||||
|
||||
qse_wchar_t* qse_wcsadup (const qse_wchar_t* str[], qse_mmgr_t* mmgr)
|
||||
qse_wchar_t* qse_wcsadup (const qse_wchar_t* str[], qse_size_t* len, qse_mmgr_t* mmgr)
|
||||
{
|
||||
qse_wchar_t* buf, * ptr;
|
||||
qse_size_t i;
|
||||
@ -181,10 +183,11 @@ qse_wchar_t* qse_wcsadup (const qse_wchar_t* str[], qse_mmgr_t* mmgr)
|
||||
ptr = buf;
|
||||
for (i = 0; str[i]; i++) ptr += qse_wcscpy (ptr, str[i]);
|
||||
|
||||
if (len) *len = capa;
|
||||
return buf;
|
||||
}
|
||||
|
||||
qse_wchar_t* qse_wcsxadup (const qse_wcstr_t str[], qse_mmgr_t* mmgr)
|
||||
qse_wchar_t* qse_wcsxadup (const qse_wcstr_t str[], qse_size_t* len, qse_mmgr_t* mmgr)
|
||||
{
|
||||
qse_wchar_t* buf, * ptr;
|
||||
qse_size_t i;
|
||||
@ -200,5 +203,6 @@ qse_wchar_t* qse_wcsxadup (const qse_wcstr_t str[], qse_mmgr_t* mmgr)
|
||||
ptr = buf;
|
||||
for (i = 0; str[i].ptr; i++) ptr += qse_wcsncpy (ptr, str[i].ptr, str[i].len);
|
||||
|
||||
if (len) *len = capa;
|
||||
return buf;
|
||||
}
|
||||
|
@ -34,6 +34,67 @@ int qse_comparehttpversions (
|
||||
return v1->major - v2->major;
|
||||
}
|
||||
|
||||
const qse_mchar_t* qse_httpstatustombs (int code)
|
||||
{
|
||||
const qse_mchar_t* msg;
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case 100: msg = QSE_MT("Continue"); break;
|
||||
case 101: msg = QSE_MT("Switching Protocols"); break;
|
||||
|
||||
case 200: msg = QSE_MT("OK"); break;
|
||||
case 201: msg = QSE_MT("Created"); break;
|
||||
case 202: msg = QSE_MT("Accepted"); break;
|
||||
case 203: msg = QSE_MT("Non-Authoritative Information"); break;
|
||||
case 204: msg = QSE_MT("No Content"); break;
|
||||
case 205: msg = QSE_MT("Reset Content"); break;
|
||||
case 206: msg = QSE_MT("Partial Content"); break;
|
||||
|
||||
case 300: msg = QSE_MT("Multiple Choices"); break;
|
||||
case 301: msg = QSE_MT("Moved Permanently"); break;
|
||||
case 302: msg = QSE_MT("Found"); break;
|
||||
case 303: msg = QSE_MT("See Other"); break;
|
||||
case 304: msg = QSE_MT("Not Modified"); break;
|
||||
case 305: msg = QSE_MT("Use Proxy"); break;
|
||||
case 307: msg = QSE_MT("Temporary Redirect"); break;
|
||||
|
||||
case 400: msg = QSE_MT("Bad Request"); break;
|
||||
case 401: msg = QSE_MT("Unauthorized"); break;
|
||||
case 402: msg = QSE_MT("Payment Required"); break;
|
||||
case 403: msg = QSE_MT("Forbidden"); break;
|
||||
case 404: msg = QSE_MT("Not Found"); break;
|
||||
case 405: msg = QSE_MT("Method Not Allowed"); break;
|
||||
case 406: msg = QSE_MT("Not Acceptable"); break;
|
||||
case 407: msg = QSE_MT("Proxy Authentication Required"); break;
|
||||
case 408: msg = QSE_MT("Request Timeout"); break;
|
||||
case 409: msg = QSE_MT("Conflict"); break;
|
||||
case 410: msg = QSE_MT("Gone"); break;
|
||||
case 411: msg = QSE_MT("Length Required"); break;
|
||||
case 412: msg = QSE_MT("Precondition Failed"); break;
|
||||
case 413: msg = QSE_MT("Request Entity Too Large"); break;
|
||||
case 414: msg = QSE_MT("Request-URI Too Long"); break;
|
||||
case 415: msg = QSE_MT("Unsupported Media Type"); break;
|
||||
case 416: msg = QSE_MT("Requested Range Not Satisfiable"); break;
|
||||
case 417: msg = QSE_MT("Expectation Failed"); break;
|
||||
case 426: msg = QSE_MT("Upgrade Required"); break;
|
||||
case 428: msg = QSE_MT("Precondition Required"); break;
|
||||
case 429: msg = QSE_MT("Too Many Requests"); break;
|
||||
case 431: msg = QSE_MT("Request Header Fields Too Large"); break;
|
||||
|
||||
case 500: msg = QSE_MT("Internal Server Error"); break;
|
||||
case 501: msg = QSE_MT("Not Implemented"); break;
|
||||
case 502: msg = QSE_MT("Bad Gateway"); break;
|
||||
case 503: msg = QSE_MT("Service Unavailable"); break;
|
||||
case 504: msg = QSE_MT("Gateway Timeout"); break;
|
||||
case 505: msg = QSE_MT("HTTP Version Not Supported"); break;
|
||||
|
||||
default: msg = QSE_MT("Unknown Error"); break;
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
const qse_mchar_t* qse_httpmethodtombs (qse_http_method_t type)
|
||||
{
|
||||
/* keep this table in the same order as qse_httpd_method_t enumerators */
|
||||
@ -410,3 +471,4 @@ qse_mchar_t* qse_perenchttpstrdup (const qse_mchar_t* str, qse_mmgr_t* mmgr)
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include "../cmn/mem.h"
|
||||
#include <qse/cmn/str.h>
|
||||
#include <qse/cmn/fmt.h>
|
||||
#include <qse/cmn/path.h>
|
||||
|
||||
#include <qse/cmn/stdio.h> /* TODO: remove this */
|
||||
|
||||
@ -30,7 +29,6 @@ typedef struct task_dir_t task_dir_t;
|
||||
struct task_dir_t
|
||||
{
|
||||
qse_mcstr_t path;
|
||||
qse_mcstr_t css;
|
||||
qse_mcstr_t qpath;
|
||||
qse_http_version_t version;
|
||||
int keepalive;
|
||||
@ -44,7 +42,6 @@ struct task_dseg_t
|
||||
int chunked;
|
||||
|
||||
qse_mcstr_t path;
|
||||
qse_mcstr_t css;
|
||||
qse_mcstr_t qpath;
|
||||
qse_ubi_t handle;
|
||||
qse_httpd_dirent_t dent;
|
||||
@ -59,13 +56,10 @@ struct task_dseg_t
|
||||
qse_size_t tcount; /* total directory entries */
|
||||
qse_size_t dcount; /* the number of items in the buffer */
|
||||
|
||||
qse_mchar_t tmbuf[128];
|
||||
qse_mchar_t fszbuf[128];
|
||||
|
||||
qse_mchar_t buf[4096];
|
||||
qse_size_t bufpos;
|
||||
qse_size_t buflen;
|
||||
qse_size_t bufrem;
|
||||
qse_mchar_t buf[4096*2];
|
||||
int bufpos;
|
||||
int buflen;
|
||||
int bufrem;
|
||||
qse_size_t chunklen;
|
||||
};
|
||||
|
||||
@ -79,9 +73,7 @@ static int task_init_dseg (
|
||||
|
||||
xtn->path.ptr = (qse_mchar_t*)(xtn + 1);
|
||||
qse_mbscpy ((qse_mchar_t*)xtn->path.ptr, arg->path.ptr);
|
||||
xtn->css.ptr = xtn->path.ptr + xtn->path.len + 1;
|
||||
qse_mbscpy ((qse_mchar_t*)xtn->css.ptr, arg->css.ptr);
|
||||
xtn->qpath.ptr = xtn->css.ptr + xtn->css.len + 1;
|
||||
xtn->qpath.ptr = xtn->path.ptr + xtn->path.len + 1;
|
||||
qse_mbscpy ((qse_mchar_t*)xtn->qpath.ptr, arg->qpath.ptr);
|
||||
|
||||
task->ctx = xtn;
|
||||
@ -135,35 +127,36 @@ static void fill_chunk_length (task_dseg_t* ctx)
|
||||
while (ctx->buf[ctx->bufpos] == QSE_MT(' ')) ctx->bufpos++;
|
||||
}
|
||||
|
||||
static int add_footer (task_dseg_t* ctx)
|
||||
static int add_footer (qse_httpd_t* httpd, qse_httpd_client_t* client, task_dseg_t* ctx)
|
||||
{
|
||||
int x;
|
||||
int x, rem;
|
||||
|
||||
if (ctx->chunked)
|
||||
rem = ctx->chunked? (ctx->buflen - 5): ctx->buflen;
|
||||
if (rem < 1)
|
||||
{
|
||||
x = snprintf (
|
||||
&ctx->buf[ctx->buflen], ctx->bufrem,
|
||||
QSE_MT("</table></body></html>\r\n0\r\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
x = snprintf (
|
||||
&ctx->buf[ctx->buflen], ctx->bufrem,
|
||||
QSE_MT("</table></body></html>"));
|
||||
}
|
||||
|
||||
if (x == -1 || x >= ctx->bufrem)
|
||||
{
|
||||
/* return an error if the buffer is too small to hold the
|
||||
* trailing footer. you need to increate the buffer size */
|
||||
httpd->errnum = QSE_HTTPD_ENOBUF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
x = httpd->rcb->format_dir (
|
||||
httpd, client, QSE_NULL, QSE_NULL,
|
||||
&ctx->buf[ctx->buflen], rem);
|
||||
if (x <= -1) return -1;
|
||||
|
||||
QSE_ASSERT (x < rem);
|
||||
|
||||
ctx->buflen += x;
|
||||
ctx->bufrem -= x;
|
||||
|
||||
/* -5 for \r\n0\r\n added above */
|
||||
if (ctx->chunked) close_chunk_data (ctx, ctx->buflen - 5);
|
||||
if (ctx->chunked)
|
||||
{
|
||||
qse_mbscpy (&ctx->buf[ctx->buflen], QSE_MT("\r\n0\r\n"));
|
||||
ctx->buflen += 5;
|
||||
ctx->bufrem -= 5;
|
||||
|
||||
/* -5 for \r\n0\r\n added above */
|
||||
if (ctx->chunked) close_chunk_data (ctx, ctx->buflen - 5);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -226,11 +219,10 @@ static int task_main_dseg (
|
||||
if (ctx->state & FOOTER_PENDING)
|
||||
{
|
||||
/* only footers yet to be sent */
|
||||
if (add_footer (ctx) <= -1)
|
||||
if (add_footer (httpd, client, ctx) <= -1)
|
||||
{
|
||||
/* return an error if the buffer is too small to hold the
|
||||
* trailing footer. you need to increate the buffer size */
|
||||
httpd->errnum = QSE_HTTPD_EINTERN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -243,31 +235,21 @@ static int task_main_dseg (
|
||||
|
||||
if (!(ctx->state & HEADER_ADDED))
|
||||
{
|
||||
int is_root;
|
||||
|
||||
is_root = (qse_mbscmp (ctx->qpath.ptr, QSE_MT("/")) == 0);
|
||||
|
||||
/* compose the header since this is the first time. */
|
||||
/* TODO: page encoding?? utf-8??? or derive name from cmgr or current locale??? */
|
||||
/* TODO: html escaping of ctx->qpath.ptr */
|
||||
x = snprintf (
|
||||
&ctx->buf[ctx->buflen], ctx->bufrem,
|
||||
QSE_MT("<html><head>%s%s%s</head><body><b>%s</b><table>%s"),
|
||||
(ctx->css.len > 0? QSE_MT("<style type='text/css'>"): QSE_MT("")),
|
||||
(ctx->css.len > 0? ctx->css.ptr: QSE_MT("")),
|
||||
(ctx->css.len > 0? QSE_MT("</style>"): QSE_MT("")),
|
||||
ctx->qpath.ptr,
|
||||
(is_root? QSE_MT(""): QSE_MT("<tr><td><a href='../'>..</a></td><td></td><td></td></tr>"))
|
||||
);
|
||||
if (x == -1 || x >= ctx->bufrem)
|
||||
x = httpd->rcb->format_dir (
|
||||
httpd, client, ctx->qpath.ptr, QSE_NULL,
|
||||
&ctx->buf[ctx->buflen], ctx->bufrem);
|
||||
if (x <= -1)
|
||||
{
|
||||
/* return an error if the buffer is too small to hold the header.
|
||||
* you need to increate the buffer size. or i have make the buffer
|
||||
* dynamic. */
|
||||
httpd->errnum = QSE_HTTPD_EINTERN;
|
||||
/* return an error if the buffer is too small to
|
||||
* hold the header(httpd->errnum == QSE_HTTPD_ENOBUF).
|
||||
* i need to increate the buffer size. or i have make
|
||||
* the buffer dynamic. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
QSE_ASSERT (x < ctx->bufrem);
|
||||
|
||||
ctx->buflen += x;
|
||||
ctx->bufrem -= x;
|
||||
|
||||
@ -291,7 +273,7 @@ static int task_main_dseg (
|
||||
{
|
||||
/* no more directory entry */
|
||||
|
||||
if (add_footer (ctx) <= -1)
|
||||
if (add_footer (httpd, client, ctx) <= -1)
|
||||
{
|
||||
/* failed to add the footer part */
|
||||
if (ctx->chunked)
|
||||
@ -309,52 +291,10 @@ static int task_main_dseg (
|
||||
if (qse_mbscmp (ctx->dent.name, QSE_MT(".")) != 0 &&
|
||||
qse_mbscmp (ctx->dent.name, QSE_MT("..")) != 0)
|
||||
{
|
||||
qse_mchar_t* encname;
|
||||
qse_btime_t bt;
|
||||
|
||||
/* TODO: better buffer management in case there are
|
||||
* a lot of file names to escape. */
|
||||
encname = qse_perenchttpstrdup (ctx->dent.name, httpd->mmgr);
|
||||
if (encname == QSE_NULL)
|
||||
{
|
||||
httpd->errnum = QSE_HTTPD_ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
qse_printf (QSE_T("ADDING [%hs]\n"), ctx->dent.name);
|
||||
|
||||
qse_localtime (ctx->dent.stat.mtime, &bt);
|
||||
snprintf (ctx->tmbuf, QSE_COUNTOF(ctx->tmbuf),
|
||||
QSE_MT("%04d-%02d-%02d %02d:%02d:%02d"),
|
||||
bt.year + QSE_BTIME_YEAR_BASE, bt.mon + 1, bt.mday,
|
||||
bt.hour, bt.min, bt.sec);
|
||||
|
||||
if (ctx->dent.stat.isdir)
|
||||
{
|
||||
ctx->fszbuf[0] = QSE_MT('\0');
|
||||
}
|
||||
else
|
||||
{
|
||||
qse_fmtuintmaxtombs (
|
||||
ctx->fszbuf, QSE_COUNTOF(ctx->fszbuf),
|
||||
ctx->dent.stat.size, 10, -1, QSE_MT('\0'), QSE_NULL
|
||||
);
|
||||
}
|
||||
|
||||
x = snprintf (
|
||||
&ctx->buf[ctx->buflen],
|
||||
ctx->bufrem,
|
||||
QSE_MT("<tr><td><a href='%s%s'>%s%s</a></td><td>%s</td><td align='right'>%s</td></tr>"),
|
||||
encname,
|
||||
(ctx->dent.stat.isdir? QSE_MT("/"): QSE_MT("")),
|
||||
ctx->dent.name, /* TODO: html escaping */
|
||||
(ctx->dent.stat.isdir? QSE_MT("/"): QSE_MT("")),
|
||||
ctx->tmbuf, ctx->fszbuf
|
||||
);
|
||||
|
||||
if (encname != ctx->dent.name) QSE_MMGR_FREE (httpd->mmgr, encname);
|
||||
|
||||
if (x == -1 || x >= ctx->bufrem)
|
||||
x = httpd->rcb->format_dir (
|
||||
httpd, client, ctx->qpath.ptr, &ctx->dent,
|
||||
&ctx->buf[ctx->buflen], ctx->bufrem);
|
||||
if (x <= -1)
|
||||
{
|
||||
/* buffer not large enough to hold this entry */
|
||||
if (ctx->dcount <= 0)
|
||||
@ -378,6 +318,8 @@ qse_printf (QSE_T("ADDING [%hs]\n"), ctx->dent.name);
|
||||
}
|
||||
else
|
||||
{
|
||||
QSE_ASSERT (x < ctx->bufrem);
|
||||
|
||||
ctx->buflen += x;
|
||||
ctx->bufrem -= x;
|
||||
ctx->dcount++;
|
||||
@ -416,7 +358,6 @@ static qse_httpd_task_t* entask_directory_segment (
|
||||
data.keepalive = dir->keepalive;
|
||||
data.chunked = dir->keepalive;
|
||||
data.path = dir->path;
|
||||
data.css = dir->css;
|
||||
data.qpath = dir->qpath;
|
||||
|
||||
QSE_MEMSET (&task, 0, QSE_SIZEOF(task));
|
||||
@ -425,7 +366,7 @@ static qse_httpd_task_t* entask_directory_segment (
|
||||
task.fini = task_fini_dseg;
|
||||
task.ctx = &data;
|
||||
|
||||
return qse_httpd_entask (httpd, client, pred, &task, QSE_SIZEOF(data) + data.path.len + 1 + data.css.len + 1 + data.qpath.len + 1);
|
||||
return qse_httpd_entask (httpd, client, pred, &task, QSE_SIZEOF(data) + data.path.len + 1 + data.qpath.len + 1);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
@ -441,9 +382,7 @@ static int task_init_dir (
|
||||
|
||||
xtn->path.ptr = (qse_mchar_t*)(xtn + 1);
|
||||
qse_mbscpy ((qse_mchar_t*)xtn->path.ptr, arg->path.ptr);
|
||||
xtn->css.ptr = xtn->path.ptr + xtn->path.len + 1;
|
||||
qse_mbscpy ((qse_mchar_t*)xtn->css.ptr, arg->css.ptr);
|
||||
xtn->qpath.ptr = xtn->css.ptr + xtn->css.len + 1;
|
||||
xtn->qpath.ptr = xtn->path.ptr + xtn->path.len + 1;
|
||||
qse_mbscpy ((qse_mchar_t*)xtn->qpath.ptr, arg->qpath.ptr);
|
||||
|
||||
/* switch the context to the extension area */
|
||||
@ -495,15 +434,10 @@ static QSE_INLINE int task_main_dir (
|
||||
}
|
||||
else
|
||||
{
|
||||
x = qse_httpd_entaskformat (
|
||||
httpd, client, x,
|
||||
QSE_MT("HTTP/%d.%d 301 Moved Permanently\r\nServer: %s\r\nDate: %s\r\nContent-Length: 0\r\nConnection: %s\r\nLocation: %s/\r\n\r\n"),
|
||||
dir->version.major, dir->version.minor,
|
||||
qse_httpd_getname (httpd),
|
||||
qse_httpd_fmtgmtimetobb (httpd, QSE_NULL, 0),
|
||||
(dir->keepalive? QSE_MT("keep-alive"): QSE_MT("close")),
|
||||
dir->qpath.ptr
|
||||
);
|
||||
x = qse_httpd_entask_redir (
|
||||
httpd, client, x, dir->qpath.ptr,
|
||||
&dir->version, dir->keepalive);
|
||||
|
||||
return (x == QSE_NULL)? -1: 0;
|
||||
}
|
||||
}
|
||||
@ -513,19 +447,14 @@ qse_httpd_task_t* qse_httpd_entaskdir (
|
||||
qse_httpd_client_t* client,
|
||||
qse_httpd_task_t* pred,
|
||||
const qse_mchar_t* path,
|
||||
const qse_mchar_t* css,
|
||||
qse_htre_t* req)
|
||||
{
|
||||
qse_httpd_task_t task;
|
||||
task_dir_t data;
|
||||
|
||||
if (css == QSE_NULL) css = QSE_MT("");
|
||||
|
||||
QSE_MEMSET (&data, 0, QSE_SIZEOF(data));
|
||||
data.path.ptr = path;
|
||||
data.path.len = qse_mbslen(data.path.ptr);
|
||||
data.css.ptr = css;
|
||||
data.css.len = qse_mbslen(data.css.ptr);
|
||||
data.qpath.ptr = qse_htre_getqpath(req);
|
||||
data.qpath.len = qse_mbslen(data.qpath.ptr);
|
||||
data.version = *qse_htre_getversion(req);
|
||||
@ -537,6 +466,6 @@ qse_httpd_task_t* qse_httpd_entaskdir (
|
||||
task.ctx = &data;
|
||||
|
||||
return qse_httpd_entask (httpd, client, pred, &task,
|
||||
QSE_SIZEOF(task_dir_t) + data.path.len + 1 + data.css.len + 1 + data.qpath.len + 1);
|
||||
QSE_SIZEOF(task_dir_t) + data.path.len + 1 + data.qpath.len + 1);
|
||||
}
|
||||
|
||||
|
@ -22,8 +22,6 @@
|
||||
#include "../cmn/mem.h"
|
||||
#include <qse/cmn/str.h>
|
||||
#include <qse/cmn/fmt.h>
|
||||
#include <qse/cmn/path.h>
|
||||
#include <qse/cmn/time.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
/* TODO: */
|
||||
@ -274,15 +272,7 @@ static QSE_INLINE int task_main_file (
|
||||
/* i've converted milliseconds to seconds before timestamp comparison
|
||||
* because st.mtime has the actual milliseconds less than 1 second
|
||||
* while if_modified_since doesn't have such small milliseconds */
|
||||
|
||||
x = qse_httpd_entaskformat (
|
||||
httpd, client, x,
|
||||
QSE_MT("HTTP/%d.%d 304 Not Modified\r\nServer: %s\r\nDate: %s\r\nConnection: %s\r\nContent-Length: 0\r\n\r\n"),
|
||||
file->version.major, file->version.minor,
|
||||
qse_httpd_getname (httpd),
|
||||
qse_httpd_fmtgmtimetobb (httpd, QSE_NULL, 0),
|
||||
(file->keepalive? QSE_MT("keep-alive"): QSE_MT("close"))
|
||||
);
|
||||
x = qse_httpd_entask_nomod (httpd, client, x, &file->version, file->keepalive);
|
||||
goto no_file_send;
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <qse/cmn/str.h>
|
||||
#include <qse/cmn/uri.h>
|
||||
#include <qse/cmn/alg.h>
|
||||
#include <qse/cmn/fmt.h>
|
||||
#include <qse/cmn/path.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
@ -1584,6 +1585,125 @@ static int handle_request (
|
||||
return process_request (httpd, client, req, 0);
|
||||
}
|
||||
|
||||
static int format_error (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client, int code, qse_mchar_t* buf, int bufsz)
|
||||
{
|
||||
int n;
|
||||
server_xtn_t* server_xtn;
|
||||
const qse_mchar_t* css, * msg;
|
||||
|
||||
server_xtn = qse_httpd_getserverxtn (httpd, client->server);
|
||||
|
||||
css = server_xtn->cfg[QSE_HTTPD_SERVER_XTN_CFG_ERRORCSS];
|
||||
if (!css) css = QSE_MT("");
|
||||
|
||||
msg = qse_httpstatustombs(code);
|
||||
|
||||
/* TODO: use my own version of snprintf replacement */
|
||||
n = snprintf (buf, bufsz,
|
||||
QSE_MT("<html><head>%s<title>%s</title></head><body><div class='header'>HTTP ERROR</div><div class='body'>%d %s</div><div class='footer'>%s</div></body></html>"),
|
||||
css, msg, code, msg, qse_httpd_getname(httpd));
|
||||
if (n < 0 || n >= bufsz)
|
||||
{
|
||||
httpd->errnum = QSE_HTTPD_ENOBUF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static int format_dir (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client,
|
||||
const qse_mchar_t* qpath, const qse_httpd_dirent_t* dirent,
|
||||
qse_mchar_t* buf, int bufsz)
|
||||
{
|
||||
/* TODO: page encoding?? utf-8??? or derive name from cmgr or current locale??? */
|
||||
/* TODO: html escaping of ctx->qpath.ptr */
|
||||
int n;
|
||||
server_xtn_t* server_xtn;
|
||||
|
||||
server_xtn = qse_httpd_getserverxtn (httpd, client->server);
|
||||
|
||||
if (dirent == QSE_NULL)
|
||||
{
|
||||
if (qpath)
|
||||
{
|
||||
/* header */
|
||||
const qse_mchar_t* css;
|
||||
int is_root = (qse_mbscmp (qpath, QSE_MT("/")) == 0);
|
||||
|
||||
css = server_xtn->cfg[QSE_HTTPD_SERVER_XTN_CFG_DIRCSS];
|
||||
if (!css) css = QSE_MT("");
|
||||
|
||||
/* TODO: html escaping of qpath */
|
||||
n = snprintf (buf, bufsz,
|
||||
QSE_MT("<html><head>%s</head><body><div class='header'>%s</div><div class='body'><table>%s"), css, qpath,
|
||||
(is_root? QSE_MT(""): QSE_MT("<tr><td class='name'><a href='../'>..</a></td><td class='time'></td><td class='size'></td></tr>"))
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* footer */
|
||||
n = snprintf (buf, bufsz, QSE_MT("</table></div><div class='footer'>%s</div></body></html>"), qse_httpd_getname(httpd));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* main entry */
|
||||
qse_mchar_t* encname;
|
||||
qse_btime_t bt;
|
||||
qse_mchar_t tmbuf[32];
|
||||
qse_mchar_t fszbuf[64];
|
||||
|
||||
/* TODO: better buffer management in case there are
|
||||
* a lot of file names to escape. */
|
||||
encname = qse_perenchttpstrdup (dirent->name, httpd->mmgr);
|
||||
if (encname == QSE_NULL)
|
||||
{
|
||||
httpd->errnum = QSE_HTTPD_ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
qse_localtime (dirent->stat.mtime, &bt);
|
||||
snprintf (tmbuf, QSE_COUNTOF(tmbuf),
|
||||
QSE_MT("%04d-%02d-%02d %02d:%02d:%02d"),
|
||||
bt.year + QSE_BTIME_YEAR_BASE, bt.mon + 1, bt.mday,
|
||||
bt.hour, bt.min, bt.sec);
|
||||
|
||||
if (dirent->stat.isdir)
|
||||
{
|
||||
fszbuf[0] = QSE_MT('\0');
|
||||
}
|
||||
else
|
||||
{
|
||||
qse_fmtuintmaxtombs (
|
||||
fszbuf, QSE_COUNTOF(fszbuf),
|
||||
dirent->stat.size, 10, -1, QSE_MT('\0'), QSE_NULL
|
||||
);
|
||||
}
|
||||
|
||||
n = snprintf (
|
||||
buf, bufsz,
|
||||
QSE_MT("<tr><td class='name'><a href='%s%s'>%s%s</a></td><td class='time'>%s</td><td class='size'>%s</td></tr>"),
|
||||
encname,
|
||||
(dirent->stat.isdir? QSE_MT("/"): QSE_MT("")),
|
||||
dirent->name, /* TODO: html escaping for entry name */
|
||||
(dirent->stat.isdir? QSE_MT("/"): QSE_MT("")),
|
||||
tmbuf, fszbuf
|
||||
);
|
||||
|
||||
if (encname != dirent->name) QSE_MMGR_FREE (httpd->mmgr, encname);
|
||||
}
|
||||
|
||||
if (n <= -1 || n >= bufsz)
|
||||
{
|
||||
httpd->errnum = QSE_HTTPD_ENOBUF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static qse_httpd_scb_t httpd_system_callbacks =
|
||||
{
|
||||
/* server */
|
||||
@ -1638,7 +1758,9 @@ static qse_httpd_scb_t httpd_system_callbacks =
|
||||
static qse_httpd_rcb_t httpd_request_callbacks =
|
||||
{
|
||||
peek_request,
|
||||
handle_request
|
||||
handle_request,
|
||||
format_error,
|
||||
format_dir
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
@ -1688,7 +1810,7 @@ static qse_mchar_t* merge_paths (
|
||||
ta[idx++] = QSE_MT("/");
|
||||
ta[idx++] = path;
|
||||
ta[idx++] = QSE_NULL;
|
||||
xpath = qse_mbsadup (ta, httpd->mmgr);
|
||||
xpath = qse_mbsadup (ta, QSE_NULL, httpd->mmgr);
|
||||
if (xpath == QSE_NULL)
|
||||
{
|
||||
httpd->errnum = QSE_HTTPD_ENOMEM;
|
||||
@ -1796,8 +1918,8 @@ static int make_resource (
|
||||
|
||||
server_xtn = qse_httpd_getserverxtn (httpd, client->server);
|
||||
|
||||
if (server_xtn->cfg[SERVER_XTN_CFG_REALM].ptr &&
|
||||
server_xtn->cfg[SERVER_XTN_CFG_BASICAUTH].ptr)
|
||||
if (server_xtn->cfg[SERVER_XTN_CFG_REALM] &&
|
||||
server_xtn->cfg[SERVER_XTN_CFG_BASICAUTH])
|
||||
{
|
||||
const qse_htre_hdrval_t* auth;
|
||||
|
||||
@ -1808,18 +1930,18 @@ static int make_resource (
|
||||
|
||||
if (qse_mbszcasecmp(auth->ptr, QSE_MT("Basic "), 6) == 0)
|
||||
{
|
||||
if (qse_mbscmp (&auth->ptr[6], server_xtn->cfg[SERVER_XTN_CFG_BASICAUTH].ptr) == 0) goto auth_ok;
|
||||
if (qse_mbscmp (&auth->ptr[6], server_xtn->cfg[SERVER_XTN_CFG_BASICAUTH]) == 0) goto auth_ok;
|
||||
}
|
||||
}
|
||||
|
||||
target->type = QSE_HTTPD_RSRC_AUTH;
|
||||
target->u.auth.realm = server_xtn->cfg[SERVER_XTN_CFG_REALM].ptr;
|
||||
target->u.auth.realm = server_xtn->cfg[SERVER_XTN_CFG_REALM];
|
||||
return 0;
|
||||
}
|
||||
|
||||
auth_ok:
|
||||
idxfile = QSE_NULL;
|
||||
xpath = merge_paths (httpd, server_xtn->cfg[SERVER_XTN_CFG_DOCROOT].ptr, qpath);
|
||||
xpath = merge_paths (httpd, server_xtn->cfg[SERVER_XTN_CFG_DOCROOT], qpath);
|
||||
if (xpath == QSE_NULL) return -1;
|
||||
|
||||
if (QSE_STAT (xpath, &st) == 0 && S_ISDIR(st.st_mode))
|
||||
@ -1854,7 +1976,6 @@ auth_ok:
|
||||
|
||||
target->type = QSE_HTTPD_RSRC_DIR;
|
||||
target->u.dir.path = xpath;
|
||||
target->u.dir.css = server_xtn->cfg[SERVER_XTN_CFG_DIRCSS].ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1862,7 +1983,7 @@ auth_ok:
|
||||
if (server_xtn->cgistd)
|
||||
{
|
||||
/* check if the request can resolve to a cgi script */
|
||||
n = attempt_cgi (httpd, server_xtn->cfg[SERVER_XTN_CFG_DOCROOT].ptr,
|
||||
n = attempt_cgi (httpd, server_xtn->cfg[SERVER_XTN_CFG_DOCROOT],
|
||||
xpath, qpath, idxfile, server_xtn->cgistd, target);
|
||||
if (n <= -1)
|
||||
{
|
||||
@ -1908,12 +2029,10 @@ static void predetach_server (qse_httpd_t* httpd, qse_httpd_server_t* server)
|
||||
|
||||
for (i = QSE_COUNTOF(server_xtn->cfg); i > 0; )
|
||||
{
|
||||
i--;
|
||||
if (server_xtn->cfg[i].ptr)
|
||||
if (server_xtn->cfg[--i])
|
||||
{
|
||||
QSE_MMGR_FREE (httpd->mmgr, server_xtn->cfg[i].ptr);
|
||||
server_xtn->cfg[i].ptr = QSE_NULL;
|
||||
server_xtn->cfg[i].len = 0;
|
||||
QSE_MMGR_FREE (httpd->mmgr, server_xtn->cfg[i]);
|
||||
server_xtn->cfg[i] = QSE_NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1925,11 +2044,11 @@ qse_httpd_server_t* qse_httpd_attachserverstd (
|
||||
qse_httpd_server_t server;
|
||||
qse_httpd_server_t* xserver;
|
||||
server_xtn_t* server_xtn;
|
||||
qse_mcstr_t tmp[4];
|
||||
const qse_mchar_t* tmp[4];
|
||||
qse_mxstr_t ba;
|
||||
qse_size_t balen2;
|
||||
|
||||
qse_uint16_t default_port;
|
||||
qse_size_t i;
|
||||
qse_uri_t xuri;
|
||||
|
||||
static qse_httpd_server_cgistd_t server_cgistd[] =
|
||||
@ -2007,49 +2126,36 @@ qse_httpd_server_t* qse_httpd_attachserverstd (
|
||||
}
|
||||
|
||||
#if defined(QSE_CHAR_IS_MCHAR)
|
||||
server_xtn->cfg[SERVER_XTN_CFG_DOCROOT].ptr = qse_mbsxdup (xuri.path.ptr, xuri.path.len, httpd->mmgr);
|
||||
if (xuri.path.ptr) server_xtn->cfg[SERVER_XTN_CFG_DOCROOT].ptr = qse_mbsxdup (xuri.path.ptr, xuri.path.len, httpd->mmgr);
|
||||
if (xuri.auth.user.ptr) server_xtn->cfg[SERVER_XTN_CFG_USERNAME].ptr = qse_mbsxdup (xuri.auth.user.ptr, xuri.auth.user.len, httpd->mmgr);
|
||||
if (xuri.auth.pass.ptr) server_xtn->cfg[SERVER_XTN_CFG_PASSWORD].ptr = qse_mbsxdup (xuri.auth.pass.ptr, xuri.auth.pass.len, httpd->mmgr);
|
||||
if (xuri.frag.ptr) server_xtn->cfg[SERVER_XTN_CFG_REALM].ptr = qse_mbsxdup (xuri.frag.ptr, xuri.frag.len, httpd->mmgr);
|
||||
server_xtn->cfg[SERVER_XTN_CFG_DOCROOT] = qse_mbsxdup (xuri.path.ptr, xuri.path.len, httpd->mmgr);
|
||||
if (xuri.path.ptr) server_xtn->cfg[SERVER_XTN_CFG_DOCROOT] = qse_mbsxdup (xuri.path.ptr, xuri.path.len, httpd->mmgr);
|
||||
if (xuri.auth.user.ptr) server_xtn->cfg[SERVER_XTN_CFG_USERNAME] = qse_mbsxdup (xuri.auth.user.ptr, xuri.auth.user.len, httpd->mmgr);
|
||||
if (xuri.auth.pass.ptr) server_xtn->cfg[SERVER_XTN_CFG_PASSWORD] = qse_mbsxdup (xuri.auth.pass.ptr, xuri.auth.pass.len, httpd->mmgr);
|
||||
if (xuri.frag.ptr) server_xtn->cfg[SERVER_XTN_CFG_REALM] = qse_mbsxdup (xuri.frag.ptr, xuri.frag.len, httpd->mmgr);
|
||||
|
||||
#else
|
||||
server_xtn->cfg[SERVER_XTN_CFG_DOCROOT].ptr = qse_wcsntombsdup (xuri.path.ptr, xuri.path.len, httpd->mmgr);
|
||||
if (xuri.auth.user.ptr) server_xtn->cfg[SERVER_XTN_CFG_USERNAME].ptr = qse_wcsntombsdup (xuri.auth.user.ptr, xuri.auth.user.len, httpd->mmgr);
|
||||
if (xuri.auth.pass.ptr) server_xtn->cfg[SERVER_XTN_CFG_PASSWORD].ptr = qse_wcsntombsdup (xuri.auth.pass.ptr, xuri.auth.pass.len, httpd->mmgr);
|
||||
if (xuri.frag.ptr) server_xtn->cfg[SERVER_XTN_CFG_REALM].ptr = qse_wcsntombsdup (xuri.frag.ptr, xuri.frag.len, httpd->mmgr);
|
||||
server_xtn->cfg[SERVER_XTN_CFG_DOCROOT] = qse_wcsntombsdup (xuri.path.ptr, xuri.path.len, httpd->mmgr);
|
||||
if (xuri.auth.user.ptr) server_xtn->cfg[SERVER_XTN_CFG_USERNAME] = qse_wcsntombsdup (xuri.auth.user.ptr, xuri.auth.user.len, httpd->mmgr);
|
||||
if (xuri.auth.pass.ptr) server_xtn->cfg[SERVER_XTN_CFG_PASSWORD] = qse_wcsntombsdup (xuri.auth.pass.ptr, xuri.auth.pass.len, httpd->mmgr);
|
||||
if (xuri.frag.ptr) server_xtn->cfg[SERVER_XTN_CFG_REALM] = qse_wcsntombsdup (xuri.frag.ptr, xuri.frag.len, httpd->mmgr);
|
||||
|
||||
#endif
|
||||
if ((!server_xtn->cfg[SERVER_XTN_CFG_DOCROOT].ptr) ||
|
||||
(xuri.auth.user.ptr && !server_xtn->cfg[SERVER_XTN_CFG_USERNAME].ptr) ||
|
||||
(xuri.auth.pass.ptr && !server_xtn->cfg[SERVER_XTN_CFG_PASSWORD].ptr) ||
|
||||
(xuri.frag.ptr && !server_xtn->cfg[SERVER_XTN_CFG_REALM].ptr)) goto nomem_after_attach;
|
||||
if ((!server_xtn->cfg[SERVER_XTN_CFG_DOCROOT]) ||
|
||||
(xuri.auth.user.ptr && !server_xtn->cfg[SERVER_XTN_CFG_USERNAME]) ||
|
||||
(xuri.auth.pass.ptr && !server_xtn->cfg[SERVER_XTN_CFG_PASSWORD]) ||
|
||||
(xuri.frag.ptr && !server_xtn->cfg[SERVER_XTN_CFG_REALM])) goto nomem_after_attach;
|
||||
|
||||
for (i = 0; i < QSE_COUNTOF(server_xtn->cfg); i++)
|
||||
{
|
||||
if (server_xtn->cfg[i].ptr)
|
||||
server_xtn->cfg[i].len = qse_mbslen(server_xtn->cfg[i].ptr);
|
||||
}
|
||||
tmp[0] = server_xtn->cfg[SERVER_XTN_CFG_USERNAME]? server_xtn->cfg[SERVER_XTN_CFG_USERNAME]: QSE_MT("");
|
||||
tmp[1] = QSE_MT(":");
|
||||
tmp[2] = server_xtn->cfg[SERVER_XTN_CFG_PASSWORD]? server_xtn->cfg[SERVER_XTN_CFG_PASSWORD]: QSE_MT("");
|
||||
tmp[3] = QSE_NULL;
|
||||
|
||||
tmp[0].ptr = server_xtn->cfg[SERVER_XTN_CFG_USERNAME].ptr? server_xtn->cfg[SERVER_XTN_CFG_USERNAME].ptr: QSE_MT("");
|
||||
tmp[0].len = server_xtn->cfg[SERVER_XTN_CFG_USERNAME].len;
|
||||
tmp[1].ptr = QSE_MT(":");
|
||||
tmp[1].len = 1;
|
||||
tmp[2].ptr = server_xtn->cfg[SERVER_XTN_CFG_PASSWORD].ptr? server_xtn->cfg[SERVER_XTN_CFG_PASSWORD].ptr: QSE_MT("");
|
||||
tmp[2].len = server_xtn->cfg[SERVER_XTN_CFG_PASSWORD].len;
|
||||
tmp[3].ptr = QSE_NULL;
|
||||
tmp[3].len = 0;
|
||||
|
||||
ba.ptr = qse_mbsxadup (tmp, httpd->mmgr);
|
||||
ba.ptr = qse_mbsadup (tmp, &ba.len, httpd->mmgr);
|
||||
if (!ba.ptr) goto nomem_after_attach;
|
||||
ba.len = tmp[0].len + tmp[1].len + tmp[2].len;
|
||||
|
||||
server_xtn->cfg[SERVER_XTN_CFG_BASICAUTH].len = ((ba.len / 3) + 1) * 4;
|
||||
server_xtn->cfg[SERVER_XTN_CFG_BASICAUTH].ptr = QSE_MMGR_ALLOC (
|
||||
httpd->mmgr,
|
||||
(server_xtn->cfg[SERVER_XTN_CFG_BASICAUTH].len + 1) * QSE_SIZEOF(qse_mchar_t)
|
||||
);
|
||||
if (!server_xtn->cfg[SERVER_XTN_CFG_BASICAUTH].ptr)
|
||||
balen2 = ((ba.len / 3) + 1) * 4;
|
||||
server_xtn->cfg[SERVER_XTN_CFG_BASICAUTH] = QSE_MMGR_ALLOC (
|
||||
httpd->mmgr, (balen2 + 1) * QSE_SIZEOF(qse_mchar_t));
|
||||
if (!server_xtn->cfg[SERVER_XTN_CFG_BASICAUTH])
|
||||
{
|
||||
QSE_MMGR_FREE (httpd->mmgr, ba.ptr);
|
||||
goto nomem_after_attach;
|
||||
@ -2057,12 +2163,12 @@ qse_httpd_server_t* qse_httpd_attachserverstd (
|
||||
|
||||
qse_enbase64 (
|
||||
ba.ptr, ba.len,
|
||||
server_xtn->cfg[SERVER_XTN_CFG_BASICAUTH].ptr,
|
||||
server_xtn->cfg[SERVER_XTN_CFG_BASICAUTH].len,
|
||||
&server_xtn->cfg[SERVER_XTN_CFG_BASICAUTH].len
|
||||
server_xtn->cfg[SERVER_XTN_CFG_BASICAUTH],
|
||||
balen2,
|
||||
&balen2
|
||||
);
|
||||
QSE_MMGR_FREE (httpd->mmgr, ba.ptr);
|
||||
server_xtn->cfg[SERVER_XTN_CFG_BASICAUTH].ptr[server_xtn->cfg[SERVER_XTN_CFG_BASICAUTH].len] = QSE_MT('\0');
|
||||
(server_xtn->cfg[SERVER_XTN_CFG_BASICAUTH])[balen2] = QSE_MT('\0');
|
||||
|
||||
server_xtn->predetach = predetach;
|
||||
server_xtn->cbstd = &server_cbstd;
|
||||
|
@ -205,96 +205,76 @@ qse_printf (QSE_T("SEND: [%.*hs]\n"), (int)l, buf);
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
typedef struct status_reloc_t status_reloc_t;
|
||||
struct status_reloc_t
|
||||
{
|
||||
const qse_mchar_t* dst;
|
||||
int redir;
|
||||
};
|
||||
|
||||
static qse_httpd_task_t* entask_status (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client,
|
||||
qse_httpd_task_t* pred, int code, void* extra,
|
||||
const qse_http_version_t* version, int keepalive)
|
||||
{
|
||||
const qse_mchar_t* msg;
|
||||
|
||||
const qse_mchar_t* extrapre = QSE_MT("");
|
||||
const qse_mchar_t* extrapst = QSE_MT("");
|
||||
const qse_mchar_t* extraval = QSE_MT("");
|
||||
|
||||
qse_mchar_t text[1024] = QSE_MT(""); /* TODO: make this buffer dynamic or scalable */
|
||||
|
||||
msg = qse_httpstatustombs (code);
|
||||
if (code == 301 || code == 307)
|
||||
{
|
||||
status_reloc_t* reloc = (status_reloc_t*)extra;
|
||||
extrapre = QSE_MT("Location: ");
|
||||
extrapst = reloc->redir? QSE_MT("/\r\n"): QSE_MT("\r\n");
|
||||
extraval = reloc->dst;
|
||||
}
|
||||
else if (code == 304)
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
||||
else
|
||||
{
|
||||
if (httpd->rcb->format_error (httpd, client, code, text, QSE_COUNTOF(text)) <= -1) return -1;
|
||||
if (code == 401)
|
||||
{
|
||||
extrapre = QSE_MT("WWW-Authenticate: Basic realm=\"");
|
||||
extrapst = QSE_MT("\"\r\n");
|
||||
extraval = (const qse_mchar_t*)extra;
|
||||
}
|
||||
}
|
||||
|
||||
return qse_httpd_entaskformat (
|
||||
httpd, client, pred,
|
||||
QSE_MT("HTTP/%d.%d %d %s\r\nServer: %s\r\nDate: %s\r\nConnection: %s\r\nContent-Type: text/html\r\nContent-Length: %lu\r\n%s%s%s\r\n%s"),
|
||||
version->major, version->minor,
|
||||
code, msg, qse_httpd_getname (httpd),
|
||||
qse_httpd_fmtgmtimetobb (httpd, QSE_NULL, 0),
|
||||
(keepalive? QSE_MT("keep-alive"): QSE_MT("close")),
|
||||
(unsigned long)qse_mbslen(text),
|
||||
extrapre, extraval, extrapst, text);
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
qse_httpd_task_t* qse_httpd_entask_error (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client,
|
||||
qse_httpd_task_t* pred, int code,
|
||||
const qse_http_version_t* version, int keepalive)
|
||||
{
|
||||
const qse_mchar_t* smsg;
|
||||
const qse_mchar_t* lmsg;
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case 403:
|
||||
smsg = QSE_MT("Forbidden");
|
||||
lmsg = QSE_MT("<html><head><title>Forbidden</title></head><body><b>FORBIDDEN<b></body></html>");
|
||||
break;
|
||||
|
||||
case 404:
|
||||
smsg = QSE_MT("Not Found");
|
||||
lmsg = QSE_MT("<html><head><title>Not Found</title></head><body><b>REQUESTED PATH NOT FOUND<b></body></html>");
|
||||
break;
|
||||
|
||||
case 405:
|
||||
smsg = QSE_MT("Method Not Allowed");
|
||||
lmsg = QSE_MT("<html><head><title>Method Not Allowed</title></head><body><b>REQUESTED METHOD NOT ALLOWED<b></body></html>");
|
||||
break;
|
||||
|
||||
case 411:
|
||||
smsg = QSE_MT("Length Required");
|
||||
lmsg = QSE_MT("<html><head><title>Length Required</title></head><body><b>LENGTH REQUIRED<b></body></html>");
|
||||
break;
|
||||
|
||||
case 416:
|
||||
smsg = QSE_MT("Requested Range Not Satisfiable");
|
||||
lmsg = QSE_MT("<html><head><title>Requested Range Not Satsfiable</title></head><body><b>REQUESTED RANGE NOT SATISFIABLE<b></body></html>");
|
||||
break;
|
||||
|
||||
case 417:
|
||||
smsg = QSE_MT("Expectation Failed");
|
||||
lmsg = QSE_MT("<html><head><title>Expectation Failed</title></head><body><b>EXPECTATION FAILED<b></body></html>");
|
||||
break;
|
||||
|
||||
case 500:
|
||||
smsg = QSE_MT("Internal Server Error");
|
||||
lmsg = QSE_MT("<html><head><title>Internal Server Error</title></head><body><b>INTERNAL SERVER ERROR<b></body></html>");
|
||||
break;
|
||||
|
||||
case 501:
|
||||
smsg = QSE_MT("Not Implemented");
|
||||
lmsg = QSE_MT("<html><head><title>Not Implemented</title></head><body><b>NOT IMPLEMENTED<b></body></html>");
|
||||
break;
|
||||
|
||||
case 502:
|
||||
smsg = QSE_MT("Bad Gateway");
|
||||
lmsg = QSE_MT("<html><head><title>Bad Gateway</title></head><body><b>BAD GATEWAY<b></body></html>");
|
||||
break;
|
||||
|
||||
case 503:
|
||||
smsg = QSE_MT("Service Unavailable");
|
||||
lmsg = QSE_MT("<html><head><title>Service Unavailable</title></head><body><b>SERVICE UNAVAILABLE<b></body></html>");
|
||||
break;
|
||||
|
||||
case 504:
|
||||
smsg = QSE_MT("Gateway Timeout");
|
||||
lmsg = QSE_MT("<html><head><title>Gateway Timeout</title></head><body><b>GATEWAY TIMEOUT<b></body></html>");
|
||||
break;
|
||||
|
||||
default:
|
||||
smsg = QSE_MT("Unknown");
|
||||
lmsg = QSE_MT("<html><head><title>Unknown Error</title></head><body><b>UNKNOWN ERROR<b></body></html>");
|
||||
break;
|
||||
}
|
||||
|
||||
return qse_httpd_entaskformat (
|
||||
httpd, client, pred,
|
||||
QSE_MT("HTTP/%d.%d %d %s\r\nServer: %s\r\nDate: %s\r\nConnection: %s\r\nContent-Type: text/html\r\nContent-Length: %lu\r\n\r\n%s\r\n\r\n"),
|
||||
version->major, version->minor, code, smsg,
|
||||
qse_httpd_getname (httpd),
|
||||
qse_httpd_fmtgmtimetobb (httpd, QSE_NULL, 0),
|
||||
(keepalive? QSE_MT("keep-alive"): QSE_MT("close")),
|
||||
(unsigned long)qse_mbslen(lmsg) + 4, lmsg
|
||||
);
|
||||
return entask_status (httpd, client, pred, code, QSE_NULL, version, keepalive);
|
||||
}
|
||||
|
||||
qse_httpd_task_t* qse_httpd_entaskerror (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client,
|
||||
qse_httpd_task_t* pred, int code, qse_htre_t* req)
|
||||
{
|
||||
return qse_httpd_entask_error (
|
||||
httpd, client, pred, code,
|
||||
qse_htre_getversion(req),
|
||||
(req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE));
|
||||
return entask_status (
|
||||
httpd, client, pred, code, QSE_NULL,
|
||||
qse_htre_getversion(req), (req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE));
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
@ -315,40 +295,94 @@ qse_httpd_task_t* qse_httpd_entaskauth (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client,
|
||||
qse_httpd_task_t* pred, const qse_mchar_t* realm, qse_htre_t* req)
|
||||
{
|
||||
const qse_http_version_t* version;
|
||||
const qse_mchar_t* lmsg;
|
||||
|
||||
version = qse_htre_getversion(req);
|
||||
lmsg = QSE_MT("<html><head><title>Unauthorized</title></head><body><b>UNAUTHORIZED<b></body></html>");
|
||||
|
||||
return qse_httpd_entaskformat (
|
||||
httpd, client, pred,
|
||||
QSE_MT("HTTP/%d.%d 401 Unauthorized\r\nServer: %s\r\nDate: %s\r\nConnection: %s\r\nWWW-Authenticate: Basic realm=\"%s\"\r\nContent-Type: text/html\r\nContent-Length: %lu\r\n\r\n%s\r\n\r\n"),
|
||||
version->major, version->minor,
|
||||
qse_httpd_getname (httpd),
|
||||
qse_httpd_fmtgmtimetobb (httpd, QSE_NULL, 0),
|
||||
((req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE)? QSE_MT("keep-alive"): QSE_MT("close")),
|
||||
realm, (unsigned long)qse_mbslen(lmsg) + 4, lmsg);
|
||||
return entask_status (
|
||||
httpd, client, pred, 401, (void*)realm,
|
||||
qse_htre_getversion(req),
|
||||
(req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE));
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
qse_httpd_task_t* qse_httpd_entask_reloc (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client,
|
||||
qse_httpd_task_t* pred, const qse_mchar_t* dst,
|
||||
const qse_http_version_t* version, int keepalive)
|
||||
{
|
||||
status_reloc_t reloc;
|
||||
|
||||
reloc.dst = dst;
|
||||
reloc.redir = 0;
|
||||
|
||||
return entask_status (
|
||||
httpd, client, pred, 301, (void*)&reloc,
|
||||
version, keepalive);
|
||||
}
|
||||
|
||||
qse_httpd_task_t* qse_httpd_entaskreloc (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client,
|
||||
qse_httpd_task_t* pred, const qse_mchar_t* dst, qse_htre_t* req)
|
||||
{
|
||||
const qse_http_version_t* version;
|
||||
status_reloc_t reloc;
|
||||
|
||||
version = qse_htre_getversion(req);
|
||||
reloc.dst = dst;
|
||||
reloc.redir = 0;
|
||||
|
||||
return qse_httpd_entaskformat (
|
||||
httpd, client, pred,
|
||||
QSE_MT("HTTP/%d.%d 301 Moved Permanently\r\nServer: %s\r\nDate: %s\r\nContent-Length: 0\r\nConnection: %s\r\nLocation: %s\r\n\r\n"),
|
||||
version->major, version->minor,
|
||||
qse_httpd_getname (httpd),
|
||||
qse_httpd_fmtgmtimetobb (httpd, QSE_NULL, 0),
|
||||
((req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE)? QSE_MT("keep-alive"): QSE_MT("close")),
|
||||
dst);
|
||||
return entask_status (
|
||||
httpd, client, pred, 301, (void*)&reloc,
|
||||
qse_htre_getversion(req),
|
||||
(req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE));
|
||||
}
|
||||
|
||||
qse_httpd_task_t* qse_httpd_entask_redir (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client,
|
||||
qse_httpd_task_t* pred, const qse_mchar_t* dst,
|
||||
const qse_http_version_t* version, int keepalive)
|
||||
{
|
||||
status_reloc_t reloc;
|
||||
|
||||
reloc.dst = dst;
|
||||
reloc.redir = 1;
|
||||
|
||||
return entask_status (
|
||||
httpd, client, pred, 301, (void*)&reloc,
|
||||
version, keepalive);
|
||||
}
|
||||
|
||||
qse_httpd_task_t* qse_httpd_entaskredir (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client,
|
||||
qse_httpd_task_t* pred, const qse_mchar_t* dst, qse_htre_t* req)
|
||||
{
|
||||
status_reloc_t reloc;
|
||||
|
||||
reloc.dst = dst;
|
||||
reloc.redir = 1;
|
||||
|
||||
return entask_status (
|
||||
httpd, client, pred, 301, (void*)&reloc,
|
||||
qse_htre_getversion(req),
|
||||
(req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE));
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
qse_httpd_task_t* qse_httpd_entask_nomod (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client,
|
||||
qse_httpd_task_t* pred, const qse_http_version_t* version, int keepalive)
|
||||
{
|
||||
return entask_status (
|
||||
httpd, client, pred, 304,
|
||||
QSE_NULL, version, keepalive);
|
||||
}
|
||||
|
||||
qse_httpd_task_t* qse_httpd_entasknomod (
|
||||
qse_httpd_t* httpd, qse_httpd_client_t* client,
|
||||
qse_httpd_task_t* pred, qse_htre_t* req)
|
||||
{
|
||||
return entask_status (
|
||||
httpd, client, pred, 304,
|
||||
QSE_NULL, qse_htre_getversion(req),
|
||||
(req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE));
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
@ -390,7 +424,7 @@ qse_httpd_task_t* qse_httpd_entaskrsrc (
|
||||
|
||||
case QSE_HTTPD_RSRC_DIR:
|
||||
qse_httpd_discardcontent (httpd, req);
|
||||
task = qse_httpd_entaskdir (httpd, client, QSE_NULL, rsrc->u.dir.path, rsrc->u.dir.css, req);
|
||||
task = qse_httpd_entaskdir (httpd, client, QSE_NULL, rsrc->u.dir.path, req);
|
||||
break;
|
||||
|
||||
case QSE_HTTPD_RSRC_ERROR:
|
||||
@ -411,6 +445,10 @@ qse_httpd_task_t* qse_httpd_entaskrsrc (
|
||||
task = qse_httpd_entaskreloc (httpd, client, QSE_NULL, rsrc->u.reloc.dst, req);
|
||||
break;
|
||||
|
||||
case QSE_HTTPD_RSRC_REDIR:
|
||||
task = qse_httpd_entaskredir (httpd, client, QSE_NULL, rsrc->u.redir.dst, req);
|
||||
break;
|
||||
|
||||
case QSE_HTTPD_RSRC_TEXT:
|
||||
task = qse_httpd_entasktext (httpd, client, QSE_NULL, rsrc->u.text.ptr, rsrc->u.text.mime, req);
|
||||
break;
|
||||
|
@ -110,6 +110,33 @@ qse_httpd_task_t* qse_httpd_entask_error (
|
||||
int keepalive
|
||||
);
|
||||
|
||||
qse_httpd_task_t* qse_httpd_entask_nomod (
|
||||
qse_httpd_t* httpd,
|
||||
qse_httpd_client_t* client,
|
||||
qse_httpd_task_t* pred,
|
||||
const qse_http_version_t* version,
|
||||
int keepalive
|
||||
);
|
||||
|
||||
qse_httpd_task_t* qse_httpd_entask_reloc (
|
||||
qse_httpd_t* httpd,
|
||||
qse_httpd_client_t* client,
|
||||
qse_httpd_task_t* pred,
|
||||
const qse_mchar_t* dst,
|
||||
const qse_http_version_t* version,
|
||||
int keepalive
|
||||
);
|
||||
|
||||
qse_httpd_task_t* qse_httpd_entask_redir (
|
||||
qse_httpd_t* httpd,
|
||||
qse_httpd_client_t* client,
|
||||
qse_httpd_task_t* pred,
|
||||
const qse_mchar_t* dst,
|
||||
const qse_http_version_t* version,
|
||||
int keepalive
|
||||
);
|
||||
|
||||
|
||||
qse_httpd_task_t* qse_httpd_entask_text (
|
||||
qse_httpd_t* httpd,
|
||||
qse_httpd_client_t* client,
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include <qse/cmn/str.h>
|
||||
#include <qse/cmn/mem.h>
|
||||
#include <qse/cmn/mbwc.h>
|
||||
#include <qse/cmn/time.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <locale.h>
|
||||
@ -71,8 +70,12 @@ static int httpd_main (int argc, qse_char_t* argv[])
|
||||
}
|
||||
|
||||
server_xtn = qse_httpd_getserverxtn (httpd, server);
|
||||
server_xtn->cfg[QSE_HTTPD_SERVER_XTN_CFG_DIRCSS].ptr = QSE_MT("body { background-color:#d0e4fe; font-size: 0.9em; font-family: Ubuntu,'Trebuchet MS',sans-serif; }");
|
||||
server_xtn->cfg[QSE_HTTPD_SERVER_XTN_CFG_DIRCSS].len = qse_mbslen(server_xtn->cfg[QSE_HTTPD_SERVER_XTN_CFG_DIRCSS].ptr);
|
||||
/* don't care about failure */
|
||||
server_xtn->cfg[QSE_HTTPD_SERVER_XTN_CFG_DIRCSS] =
|
||||
qse_mbsdup (QSE_MT("<style type='text/css'>body { background-color:#d0e4fe; font-size: 0.9em; } div.header { font-weight: bold; margin-bottom: 5px; } div.footer { border-top: 1px solid #99AABB; text-align: right; } table { font-size: 0.9em; } td { white-space: nowrap; } td.size { text-align: right; }</style>"), qse_httpd_getmmgr(httpd));
|
||||
|
||||
server_xtn->cfg[QSE_HTTPD_SERVER_XTN_CFG_ERRORCSS] =
|
||||
qse_mbsdup (QSE_MT("<style type='text/css'>body { background-color:#d0e4fe; font-size: 0.9em; } div.header { font-weight: bold; margin-bottom: 5px; } div.footer { border-top: 1px solid #99AABB; text-align: right; }</style>"), qse_httpd_getmmgr(httpd));
|
||||
}
|
||||
|
||||
g_httpd = httpd;
|
||||
|
Loading…
Reference in New Issue
Block a user