simplified relocation handling
deleted qse_httpd_entaskredir() and related definitions added virtual(function pointer) cgi support. improved pio to read /dev/fd implemented QSE_PIO_FNCCMD for qse_pio_t
This commit is contained in:
@ -437,7 +437,7 @@ static qse_wchar_t* get_env (qse_env_t* env, const qse_wchar_t* name, int* free)
|
||||
*free = 0;
|
||||
return eq + 1;
|
||||
}
|
||||
p++;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
*/
|
||||
@ -464,10 +464,10 @@ static qse_wchar_t* get_env (qse_env_t* env, const qse_wchar_t* name, int* free)
|
||||
|
||||
QSE_MMGR_FREE (env->mmgr, dup);
|
||||
|
||||
p++;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -494,10 +494,10 @@ static qse_mchar_t* get_env (qse_env_t* env, const qse_mchar_t* name, int* free)
|
||||
*free = 0;
|
||||
return eq + 1;
|
||||
}
|
||||
p++;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@ -587,14 +587,14 @@ static int load_curenv (qse_env_t* env)
|
||||
if (*envstr != QSE_WT('=') &&
|
||||
add_envstrw (env, envstr) <= -1) { ret = -1; goto done; }
|
||||
envstr += qse_wcslen (envstr) + 1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
while (*envstr != QSE_MT('\0'))
|
||||
{
|
||||
if (*envstr != QSE_MT('=') &&
|
||||
add_envstrm (env, envstr) <= -1) { ret = -1; goto done; }
|
||||
envstr += qse_mbslen (envstr) + 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
done:
|
||||
@ -614,7 +614,7 @@ done:
|
||||
while (*p)
|
||||
{
|
||||
if (add_envstrw (env, *p) <= -1) return -1;
|
||||
p++;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
*/
|
||||
@ -635,11 +635,10 @@ done:
|
||||
QSE_MMGR_FREE (env->mmgr, dup);
|
||||
if (n <= -1) return -1;
|
||||
|
||||
p++;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
#else
|
||||
@ -656,10 +655,10 @@ done:
|
||||
while (*p)
|
||||
{
|
||||
if (add_envstrm (env, *p) <= -1) return -1;
|
||||
p++;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
1047
qse/lib/cmn/pio.c
1047
qse/lib/cmn/pio.c
File diff suppressed because it is too large
Load Diff
@ -316,7 +316,7 @@ qse_task_slice_t* qse_task_create (
|
||||
tmp = ((qse_uint8_t*)(slice + 1)) + stksize - QSE_SIZEOF(void*);
|
||||
|
||||
tmp = (qse_uint8_t*)tmp - QSE_SIZEOF(void*);
|
||||
*(void**)tmp = NULL; /* t1 */
|
||||
*(void**)tmp = QSE_NULL; /* t1 */
|
||||
|
||||
tmp = (qse_uint8_t*)tmp - QSE_SIZEOF(void*);
|
||||
*(void**)tmp = slice; /* t2 */
|
||||
|
@ -56,6 +56,7 @@ const qse_mchar_t* qse_httpstatustombs (int code)
|
||||
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 308: msg = QSE_MT("Permanent Redirect"); break;
|
||||
|
||||
case 400: msg = QSE_MT("Bad Request"); break;
|
||||
case 401: msg = QSE_MT("Unauthorized"); break;
|
||||
|
@ -44,6 +44,7 @@ struct task_cgi_arg_t
|
||||
qse_mcstr_t root;
|
||||
qse_mcstr_t shebang;
|
||||
int nph;
|
||||
qse_httpd_fnc_t fnc;
|
||||
qse_htre_t* req;
|
||||
};
|
||||
|
||||
@ -63,6 +64,7 @@ struct task_cgi_t
|
||||
qse_http_version_t version;
|
||||
int keepalive; /* taken from the request */
|
||||
int nph;
|
||||
qse_pio_fnc_t fnc;
|
||||
|
||||
qse_htrd_t* script_htrd;
|
||||
qse_env_t* env;
|
||||
@ -705,7 +707,7 @@ static int task_init_cgi (
|
||||
qse_size_t len;
|
||||
const qse_mchar_t* ptr;
|
||||
const qse_htre_hdrval_t* tmp;
|
||||
|
||||
|
||||
cgi = (task_cgi_t*)qse_httpd_gettaskxtn (httpd, task);
|
||||
arg = (task_cgi_arg_t*)task->ctx;
|
||||
|
||||
@ -733,6 +735,12 @@ static int task_init_cgi (
|
||||
cgi->keepalive = (arg->req->flags & QSE_HTRE_ATTR_KEEPALIVE);
|
||||
cgi->nph = arg->nph;
|
||||
cgi->req = QSE_NULL;
|
||||
if (arg->fnc.ptr)
|
||||
{
|
||||
/* the function pointer is set */
|
||||
cgi->fnc.ptr = arg->fnc.ptr;
|
||||
cgi->fnc.ctx = arg->fnc.ctx;
|
||||
}
|
||||
|
||||
content_length = 0;
|
||||
if (arg->req->state & QSE_HTRE_DISCARDED) goto done;
|
||||
@ -1432,6 +1440,7 @@ static int task_main_cgi (
|
||||
cgi_script_htrd_xtn_t* xtn;
|
||||
cgi->script_htrd = qse_htrd_open (httpd->mmgr, QSE_SIZEOF(cgi_script_htrd_xtn_t));
|
||||
if (cgi->script_htrd == QSE_NULL) goto oops;
|
||||
|
||||
xtn = (cgi_script_htrd_xtn_t*) qse_htrd_getxtn (cgi->script_htrd);
|
||||
xtn->cgi = cgi;
|
||||
xtn->task = task;
|
||||
@ -1460,22 +1469,30 @@ static int task_main_cgi (
|
||||
if (httpd->opt.trait & QSE_HTTPD_CGINOCLOEXEC)
|
||||
pio_options |= QSE_PIO_NOCLOEXEC;
|
||||
|
||||
if (cgi->shebang[0] != QSE_MT('\0'))
|
||||
if (cgi->fnc.ptr)
|
||||
{
|
||||
const qse_mchar_t* tmp[4];
|
||||
tmp[0] = cgi->shebang;
|
||||
tmp[1] = QSE_MT(" ");
|
||||
tmp[2] = cgi->path;
|
||||
tmp[3] = QSE_NULL;
|
||||
xpath = qse_mbsadup (tmp, QSE_NULL, httpd->mmgr);
|
||||
if (xpath == QSE_NULL) goto oops;
|
||||
xpath = (qse_mchar_t*)&cgi->fnc;
|
||||
pio_options |= QSE_PIO_FNCCMD;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cgi->shebang[0] != QSE_MT('\0'))
|
||||
{
|
||||
const qse_mchar_t* tmp[4];
|
||||
tmp[0] = cgi->shebang;
|
||||
tmp[1] = QSE_MT(" ");
|
||||
tmp[2] = cgi->path;
|
||||
tmp[3] = QSE_NULL;
|
||||
xpath = qse_mbsadup (tmp, QSE_NULL, httpd->mmgr);
|
||||
if (xpath == QSE_NULL) goto oops;
|
||||
}
|
||||
else xpath = cgi->path;
|
||||
}
|
||||
else xpath = cgi->path;
|
||||
|
||||
x = qse_pio_init (
|
||||
&cgi->pio, httpd->mmgr, (const qse_char_t*)xpath,
|
||||
cgi->env, pio_options);
|
||||
if (xpath != cgi->path) QSE_MMGR_FREE (httpd->mmgr, xpath);
|
||||
if (xpath != cgi->path && xpath != &cgi->fnc) QSE_MMGR_FREE (httpd->mmgr, xpath);
|
||||
|
||||
if (x <= -1)
|
||||
{
|
||||
@ -1539,6 +1556,12 @@ static int task_main_cgi (
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no forwarding buffer. the request should not send any contents
|
||||
* to the cgi script. close the input to the script */
|
||||
qse_pio_end (&cgi->pio, QSE_PIO_IN);
|
||||
}
|
||||
|
||||
task->main = cgi->nph? task_main_cgi_4_nph: task_main_cgi_2;
|
||||
return 1;
|
||||
@ -1575,11 +1598,35 @@ qse_httpd_task_t* qse_httpd_entaskcgi (
|
||||
task_cgi_arg_t arg;
|
||||
qse_httpd_rsrc_cgi_t rsrc;
|
||||
|
||||
QSE_MEMSET (&arg, 0, QSE_SIZEOF(arg));
|
||||
|
||||
rsrc = *cgi;
|
||||
if (rsrc.flags & QSE_HTTPD_RSRC_CGI_FNC)
|
||||
{
|
||||
/* rsrc.script must carry a pointer to qse_pio_fnc_t */
|
||||
if (rsrc.script == QSE_NULL || ((qse_pio_fnc_t*)rsrc.script)->ptr == QSE_NULL)
|
||||
{
|
||||
httpd->errnum = QSE_HTTPD_EINVAL;
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
arg.fnc.ptr = (qse_httpd_fncptr_t)rsrc.path;
|
||||
arg.fnc.ctx = (void*)rsrc.shebang;
|
||||
|
||||
/* reset the script to an empty string for less interference
|
||||
* with code handling normal script */
|
||||
rsrc.path = QSE_MT("");
|
||||
rsrc.shebang = QSE_MT("");
|
||||
}
|
||||
else
|
||||
{
|
||||
QSE_ASSERT (rsrc.path != QSE_NULL);
|
||||
if (rsrc.shebang == QSE_NULL) rsrc.shebang = QSE_MT("");
|
||||
}
|
||||
|
||||
if (rsrc.script == QSE_NULL) rsrc.script = qse_htre_getqpath(req);
|
||||
if (rsrc.suffix == QSE_NULL) rsrc.suffix = QSE_MT("");
|
||||
if (rsrc.root == QSE_NULL) rsrc.root = QSE_MT("");
|
||||
if (rsrc.shebang == QSE_NULL) rsrc.shebang = QSE_MT("");
|
||||
|
||||
arg.path.ptr = (qse_mchar_t*)rsrc.path;
|
||||
arg.path.len = qse_mbslen(rsrc.path);
|
||||
@ -1589,7 +1636,7 @@ qse_httpd_task_t* qse_httpd_entaskcgi (
|
||||
arg.suffix.len = qse_mbslen(rsrc.suffix);
|
||||
arg.root.ptr = (qse_mchar_t*)rsrc.root;
|
||||
arg.root.len = qse_mbslen(rsrc.root);
|
||||
arg.nph = rsrc.nph;
|
||||
arg.nph = ((rsrc.flags & QSE_HTTPD_RSRC_CGI_NPH) != 0);
|
||||
arg.shebang.ptr = (qse_mchar_t*)rsrc.shebang;
|
||||
arg.shebang.len = qse_mbslen(rsrc.shebang);
|
||||
arg.req = req;
|
||||
|
@ -1983,7 +1983,7 @@ printf ("XXXXXXXXXXXXXXXXXXXXXXXXXX URL REWRITTEN TO [%s].....\n", new_url);
|
||||
{
|
||||
/* check if it begins with redirection code followed by a colon */
|
||||
int redir_code = 0;
|
||||
qse_httpd_status_reloc_t reloc;
|
||||
qse_httpd_rsrc_reloc_t reloc;
|
||||
const qse_mchar_t* nuptr = new_url;
|
||||
do
|
||||
{
|
||||
@ -1996,11 +1996,14 @@ printf ("XXXXXXXXXXXXXXXXXXXXXXXXXX URL REWRITTEN TO [%s].....\n", new_url);
|
||||
/* no colon is found after digits. it's probably a normal url */
|
||||
goto normal_url;
|
||||
}
|
||||
if (redir_code != 301 && redir_code != 302 && redir_code != 307) redir_code = 301;
|
||||
if (redir_code != 301 && redir_code != 302 && redir_code != 303 &&
|
||||
redir_code != 307 && redir_code != 308) redir_code = 302;
|
||||
nuptr++;
|
||||
|
||||
/* relocation code is given explictly, no slash appending is needed.
|
||||
* use qse_httpd_entask_status() rather than qse_httpd_entaskreloc(). */
|
||||
reloc.flags = 0;
|
||||
reloc.dst = nuptr;
|
||||
reloc.redir = 0; /* don't want to append extra / */
|
||||
|
||||
if (qse_httpd_entask_status (
|
||||
httpd, proxy->client, proxy->task, redir_code, &reloc,
|
||||
|
@ -1547,7 +1547,7 @@ static int file_stat (
|
||||
* for a file. it is mainly used to get a file size and timestamps
|
||||
* of a regular file. so it should fail for a non-regular file.
|
||||
* note that STAT_REG is passed to stat_file for it */
|
||||
return stat_file (httpd, path, hst, STAT_REG);
|
||||
return stat_file (httpd, path, hst, STAT_REG);
|
||||
}
|
||||
|
||||
static int file_purge (qse_httpd_t* httpd, const qse_mchar_t* path)
|
||||
@ -2444,10 +2444,13 @@ static void free_resource (
|
||||
QSE_MMGR_FREE (httpd->mmgr, (qse_mchar_t*)target->u.cgi.suffix);
|
||||
if (target->u.cgi.script != qpath)
|
||||
QSE_MMGR_FREE (httpd->mmgr, (qse_mchar_t*)target->u.cgi.script);
|
||||
if (target->u.cgi.path != qpath)
|
||||
QSE_MMGR_FREE (httpd->mmgr, (qse_mchar_t*)target->u.cgi.path);
|
||||
if (target->u.cgi.shebang)
|
||||
QSE_MMGR_FREE (httpd->mmgr, (qse_mchar_t*)target->u.cgi.shebang);
|
||||
if (!(target->u.cgi.flags & QSE_HTTPD_RSRC_CGI_FNC))
|
||||
{
|
||||
if (target->u.cgi.path != qpath)
|
||||
QSE_MMGR_FREE (httpd->mmgr, (qse_mchar_t*)target->u.cgi.path);
|
||||
if (target->u.cgi.shebang)
|
||||
QSE_MMGR_FREE (httpd->mmgr, (qse_mchar_t*)target->u.cgi.shebang);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@ -2457,8 +2460,8 @@ static void free_resource (
|
||||
break;
|
||||
|
||||
case QSE_HTTPD_RSRC_FILE:
|
||||
if (target->u.cgi.path != qpath)
|
||||
QSE_MMGR_FREE (httpd->mmgr, (qse_mchar_t*)target->u.cgi.path);
|
||||
if (target->u.file.path != qpath)
|
||||
QSE_MMGR_FREE (httpd->mmgr, (qse_mchar_t*)target->u.file.path);
|
||||
break;
|
||||
|
||||
case QSE_HTTPD_RSRC_RELOC:
|
||||
@ -2466,11 +2469,6 @@ static void free_resource (
|
||||
QSE_MMGR_FREE (httpd->mmgr, (qse_mchar_t*)target->u.reloc.dst);
|
||||
break;
|
||||
|
||||
case QSE_HTTPD_RSRC_REDIR:
|
||||
if (target->u.redir.dst != qpath)
|
||||
QSE_MMGR_FREE (httpd->mmgr, (qse_mchar_t*)target->u.redir.dst);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* nothing to do */
|
||||
break;
|
||||
@ -2573,22 +2571,19 @@ static int attempt_cgi (
|
||||
#endif
|
||||
|
||||
/* create a relocation resource */
|
||||
QSE_MEMSET (target, 0, QSE_SIZEOF(*target));
|
||||
target->type = QSE_HTTPD_RSRC_RELOC;
|
||||
target->u.reloc.dst = merge_paths (httpd, tmp->qpath, tmp->idxfile);
|
||||
if (target->u.reloc.dst == QSE_NULL) goto oops;
|
||||
|
||||
/* free tmp->xpath here upon success since it's not used for relocation.
|
||||
* it is freed by the called upon failure so the 'oops' part don't free it */
|
||||
* upon failure, it is freed by the caller. so the 'oops' part
|
||||
* of this function doesn't free it. */
|
||||
QSE_MMGR_FREE (httpd->mmgr, tmp->xpath);
|
||||
return 1;
|
||||
}
|
||||
else script = (qse_mchar_t*)tmp->qpath;
|
||||
|
||||
if (cgi.shebang)
|
||||
{
|
||||
shebang = qse_mbsdup (cgi.shebang, httpd->mmgr);
|
||||
if (shebang == QSE_NULL) goto oops;
|
||||
}
|
||||
|
||||
goto bingo;
|
||||
}
|
||||
}
|
||||
@ -2619,14 +2614,13 @@ static int attempt_cgi (
|
||||
*/
|
||||
merge_paths_to_buf (httpd, tmp->root.u.path.val, tmp->qpath_rp, slash - tmp->qpath_rp, tmp->xpath);
|
||||
xpath_changed = 1;
|
||||
|
||||
|
||||
stx = stat_file (httpd, tmp->xpath, &st, 0);
|
||||
if (stx <= -1)
|
||||
{
|
||||
/* stop at the current segment if stating fails.
|
||||
* if the current semgment can't be stat-ed, it's not likely that
|
||||
* the next segment can be successfully stat-ed */
|
||||
break;
|
||||
/* instead of stopping here, let's give a non-existent
|
||||
* segment to be a virtual cgi script(function pointer). */
|
||||
st.isdir = 0;
|
||||
}
|
||||
|
||||
if (!st.isdir)
|
||||
@ -2636,9 +2630,16 @@ static int attempt_cgi (
|
||||
QSE_MEMSET (&qinfo, 0, QSE_SIZEOF(qinfo));
|
||||
qinfo.req = req;
|
||||
qinfo.xpath = tmp->xpath;
|
||||
qinfo.xpath_nx = (stx <= -1);
|
||||
|
||||
if (server_xtn->query (httpd, client->server, QSE_HTTPD_SERVERSTD_CGI, &qinfo, &cgi) >= 0 && cgi.cgi)
|
||||
{
|
||||
if (cgi.fncptr == QSE_NULL && stx <= -1)
|
||||
{
|
||||
/* normal cgi script must exist. */
|
||||
break;
|
||||
}
|
||||
|
||||
/* the script name is composed of the orginal query path.
|
||||
* the pointer held in 'slash' is valid for tmp->qpath as
|
||||
* tmp->qpath_rp is at most the tail part of tmp->qpath. */
|
||||
@ -2646,23 +2647,57 @@ static int attempt_cgi (
|
||||
suffix = qse_mbsdup (slash, httpd->mmgr);
|
||||
if (!script || !suffix) goto oops;
|
||||
|
||||
if (cgi.shebang)
|
||||
{
|
||||
shebang = qse_mbsdup (cgi.shebang, httpd->mmgr);
|
||||
if (shebang == QSE_NULL) goto oops;
|
||||
}
|
||||
|
||||
goto bingo;
|
||||
}
|
||||
}
|
||||
|
||||
if (stx <= -1)
|
||||
{
|
||||
/* stop at the current segment if stat() fails.
|
||||
* if the current segment can't be stat-ed, it's not likely that
|
||||
* the next segment can be stat-ed successfully */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ptr = slash + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no more slash is found. the last segement doesn't have to be checked
|
||||
* here since it's attempted by the caller. */
|
||||
/* no more slash is found. this is the last segment.
|
||||
* the caller has called stat() against the last segment
|
||||
* before having called this function. so it's known
|
||||
* that the path disn't exist.
|
||||
*
|
||||
* however, a virtual cgi script may not exist. a check
|
||||
* for it is still required here */
|
||||
|
||||
qse_httpd_serverstd_query_info_t qinfo;
|
||||
|
||||
if (xpath_changed)
|
||||
{
|
||||
/* restore the tmp->xpath to the original value by
|
||||
* combining the full path with the document root. */
|
||||
merge_paths_to_buf (httpd, tmp->root.u.path.val, tmp->qpath_rp, (qse_size_t)-1, tmp->xpath);
|
||||
xpath_changed = 0;
|
||||
}
|
||||
|
||||
QSE_MEMSET (&qinfo, 0, QSE_SIZEOF(qinfo));
|
||||
qinfo.req = req;
|
||||
qinfo.xpath = tmp->xpath;
|
||||
qinfo.xpath_nx = 1;
|
||||
|
||||
if (server_xtn->query (httpd, client->server, QSE_HTTPD_SERVERSTD_CGI, &qinfo, &cgi) >= 0 && cgi.cgi && cgi.fncptr)
|
||||
{
|
||||
/* virtual cgi script */
|
||||
script = qse_mbsdup (tmp->qpath, httpd->mmgr);
|
||||
if (!script) goto oops;
|
||||
suffix = QSE_NULL;
|
||||
|
||||
goto bingo;
|
||||
}
|
||||
|
||||
/* not a virtual cgi script. just break */
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2675,12 +2710,32 @@ static int attempt_cgi (
|
||||
|
||||
bingo:
|
||||
target->type = QSE_HTTPD_RSRC_CGI;
|
||||
target->u.cgi.nph = cgi.nph;
|
||||
target->u.cgi.path = tmp->xpath;
|
||||
target->u.cgi.flags = 0;
|
||||
if (cgi.nph) target->u.cgi.flags |= QSE_HTTPD_RSRC_CGI_NPH;
|
||||
|
||||
if (cgi.fncptr)
|
||||
{
|
||||
/* the type casting here is guly */
|
||||
target->u.cgi.path = (qse_mchar_t*)cgi.fncptr;
|
||||
target->u.cgi.shebang = cgi.shebang;
|
||||
target->u.cgi.flags |= QSE_HTTPD_RSRC_CGI_FNC;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cgi.shebang)
|
||||
{
|
||||
shebang = qse_mbsdup (cgi.shebang, httpd->mmgr);
|
||||
if (shebang == QSE_NULL) goto oops;
|
||||
}
|
||||
|
||||
target->u.cgi.path = tmp->xpath;
|
||||
target->u.cgi.shebang = shebang;
|
||||
}
|
||||
|
||||
target->u.cgi.script = script;
|
||||
target->u.cgi.suffix = suffix;
|
||||
target->u.cgi.root = tmp->root.u.path.val;
|
||||
target->u.cgi.shebang = shebang;
|
||||
|
||||
return 1;
|
||||
|
||||
oops:
|
||||
@ -2739,6 +2794,13 @@ static int make_resource (
|
||||
/* handle the request locally */
|
||||
QSE_ASSERT (tmp.root.type == QSE_HTTPD_SERVERSTD_ROOT_PATH);
|
||||
|
||||
/*****************************************************************************
|
||||
* BUG BUG BUG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1
|
||||
* TODO: calling the realm query here is wrong especially if the prefix path is resolved to a cgi.
|
||||
* for example, /abc/def/test.cgi/x/y/z,
|
||||
* when this function queries for REALM, it's not known that /abc/def/test.cgi is a cgi script.
|
||||
|
||||
*****************************************************************************/
|
||||
if (server_xtn->query (httpd, client->server, QSE_HTTPD_SERVERSTD_REALM, &qinfo, &tmp.realm) <= -1 ||
|
||||
server_xtn->query (httpd, client->server, QSE_HTTPD_SERVERSTD_INDEX, &qinfo, &tmp.index) <= -1)
|
||||
{
|
||||
@ -2877,7 +2939,7 @@ auth_ok:
|
||||
tmp.xpath = tpath;
|
||||
tmp.idxfile = ptr;
|
||||
goto attempt_file;
|
||||
}
|
||||
}
|
||||
|
||||
QSE_MMGR_FREE (httpd->mmgr, tpath);
|
||||
}
|
||||
@ -2898,8 +2960,9 @@ auth_ok:
|
||||
{
|
||||
/* the query path doesn't end with a slash. so redirect it */
|
||||
qse_htre_discardcontent (req);
|
||||
target->type = QSE_HTTPD_RSRC_REDIR;
|
||||
target->u.redir.dst = tmp.qpath;
|
||||
target->type = QSE_HTTPD_RSRC_RELOC;
|
||||
target->u.reloc.flags = QSE_HTTPD_RSRC_RELOC_APPENDSLASH | QSE_HTTPD_RSRC_RELOC_PERMANENT;
|
||||
target->u.reloc.dst = tmp.qpath;
|
||||
/* free xpath since it won't be used */
|
||||
QSE_MMGR_FREE (httpd->mmgr, tmp.xpath);
|
||||
}
|
||||
@ -2929,7 +2992,16 @@ auth_ok:
|
||||
QSE_MMGR_FREE (httpd->mmgr, tmp.xpath);
|
||||
return -1;
|
||||
}
|
||||
if (n >= 1) return 0;
|
||||
if (n >= 1)
|
||||
{
|
||||
if (target->u.cgi.flags & QSE_HTTPD_RSRC_CGI_FNC)
|
||||
{
|
||||
/* tmp.xpath is not set to target->u.cgi.path when
|
||||
* this flag is set. it must be deallocated */
|
||||
QSE_MMGR_FREE (httpd->mmgr, tmp.xpath);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
qinfo.xpath = tmp.xpath;
|
||||
|
||||
@ -3015,8 +3087,8 @@ struct cgi_tab_t
|
||||
};
|
||||
static struct cgi_tab_t cgitab[] =
|
||||
{
|
||||
{ QSE_MT(".cgi"), { 1, 0, QSE_NULL } },
|
||||
{ QSE_MT(".nph"), { 1, 1, QSE_NULL } },
|
||||
{ QSE_MT(".cgi"), { 1, 0, QSE_NULL, QSE_NULL } },
|
||||
{ QSE_MT(".nph"), { 1, 1, QSE_NULL, QSE_NULL } },
|
||||
};
|
||||
|
||||
static int query_server (
|
||||
@ -3071,12 +3143,18 @@ static int query_server (
|
||||
case QSE_HTTPD_SERVERSTD_CGI:
|
||||
{
|
||||
qse_httpd_serverstd_cgi_t* cgi = (qse_httpd_serverstd_cgi_t*)result;
|
||||
for (i = 0; i < QSE_COUNTOF(cgitab); i++)
|
||||
|
||||
if (!qinfo->xpath_nx)
|
||||
{
|
||||
if (qse_mbsend (qinfo->xpath, cgitab[i].suffix))
|
||||
/* this standard implementation supports a normal cgi script only */
|
||||
|
||||
for (i = 0; i < QSE_COUNTOF(cgitab); i++)
|
||||
{
|
||||
QSE_MEMCPY (cgi, &cgitab[i].cgi, QSE_SIZEOF(*cgi));
|
||||
return 0;
|
||||
if (qse_mbsend (qinfo->xpath, cgitab[i].suffix))
|
||||
{
|
||||
QSE_MEMCPY (cgi, &cgitab[i].cgi, QSE_SIZEOF(*cgi));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,14 +178,16 @@ qse_httpd_task_t* qse_httpd_entask_status (
|
||||
msg = qse_httpstatustombs (code);
|
||||
switch (code)
|
||||
{
|
||||
case 301:
|
||||
case 302:
|
||||
case 307:
|
||||
case 301: /* Moved Permanently */
|
||||
case 302: /* Found */
|
||||
case 303: /* See Other (since HTTP/1.1) */
|
||||
case 307: /* Temporary Redirect (since HTTP/1.1) */
|
||||
case 308: /* Permanent Redirect (Experimental RFC; RFC 7238) */
|
||||
{
|
||||
qse_httpd_status_reloc_t* reloc;
|
||||
reloc = (qse_httpd_status_reloc_t*)extra;
|
||||
qse_httpd_rsrc_reloc_t* reloc;
|
||||
reloc = (qse_httpd_rsrc_reloc_t*)extra;
|
||||
extrapre = QSE_MT("Location: ");
|
||||
extrapst = reloc->redir? QSE_MT("/\r\n"): QSE_MT("\r\n");
|
||||
extrapst = (reloc->flags & QSE_HTTPD_RSRC_RELOC_APPENDSLASH)? QSE_MT("/\r\n"): QSE_MT("\r\n");
|
||||
extraval = reloc->dst;
|
||||
break;
|
||||
}
|
||||
@ -276,31 +278,22 @@ qse_httpd_task_t* qse_httpd_entaskauth (
|
||||
|
||||
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)
|
||||
qse_httpd_task_t* pred, const qse_httpd_rsrc_reloc_t* reloc, qse_htre_t* req)
|
||||
{
|
||||
qse_httpd_status_reloc_t reloc;
|
||||
int code;
|
||||
|
||||
reloc.dst = dst;
|
||||
reloc.redir = 0;
|
||||
if (reloc->flags & QSE_HTTPD_RSRC_RELOC_KEEPMETHOD)
|
||||
{
|
||||
code = (reloc->flags & QSE_HTTPD_RSRC_RELOC_PERMANENT)? 308: 307;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* NOTE: 302 can be 303 for HTTP/1.1 */
|
||||
code = (reloc->flags & QSE_HTTPD_RSRC_RELOC_PERMANENT)? 301: 302;
|
||||
}
|
||||
|
||||
return qse_httpd_entask_status (
|
||||
httpd, client, pred, 301, (void*)&reloc,
|
||||
qse_htre_getqmethodtype(req),
|
||||
qse_htre_getversion(req),
|
||||
(req->flags & QSE_HTRE_ATTR_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)
|
||||
{
|
||||
qse_httpd_status_reloc_t reloc;
|
||||
|
||||
reloc.dst = dst;
|
||||
reloc.redir = 1;
|
||||
|
||||
return qse_httpd_entask_status (
|
||||
httpd, client, pred, 301, (void*)&reloc,
|
||||
httpd, client, pred, code, (void*)reloc,
|
||||
qse_htre_getqmethodtype(req),
|
||||
qse_htre_getversion(req),
|
||||
(req->flags & QSE_HTRE_ATTR_KEEPALIVE));
|
||||
@ -403,11 +396,7 @@ qse_httpd_task_t* qse_httpd_entaskrsrc (
|
||||
break;
|
||||
|
||||
case QSE_HTTPD_RSRC_RELOC:
|
||||
task = qse_httpd_entaskreloc (httpd, client, pred, rsrc->u.reloc.dst, req);
|
||||
break;
|
||||
|
||||
case QSE_HTTPD_RSRC_REDIR:
|
||||
task = qse_httpd_entaskredir (httpd, client, pred, rsrc->u.redir.dst, req);
|
||||
task = qse_httpd_entaskreloc (httpd, client, pred, &rsrc->u.reloc, req);
|
||||
break;
|
||||
|
||||
case QSE_HTTPD_RSRC_TEXT:
|
||||
|
@ -100,13 +100,6 @@ struct qse_httpd_real_task_t
|
||||
qse_httpd_real_task_t* next;
|
||||
};
|
||||
|
||||
typedef struct qse_httpd_status_reloc_t qse_httpd_status_reloc_t;
|
||||
struct qse_httpd_status_reloc_t
|
||||
{
|
||||
const qse_mchar_t* dst;
|
||||
int redir;
|
||||
};
|
||||
|
||||
#define MAX_SEND_SIZE 4096
|
||||
#define MAX_RECV_SIZE 4096
|
||||
|
||||
|
Reference in New Issue
Block a user