added qse_env_append() and related functions.
fixed how to handle multiple values with the same key when setting an environment variable for a cgi script
This commit is contained in:
@ -111,8 +111,6 @@ struct cgi_client_req_hdr_ctx_t
|
||||
qse_env_t* env;
|
||||
};
|
||||
|
||||
|
||||
|
||||
static int cgi_capture_client_header (
|
||||
qse_htre_t* req, const qse_mchar_t* key, const qse_htre_hdrval_t* val, void* ctx)
|
||||
{
|
||||
@ -140,8 +138,6 @@ static int cgi_capture_client_header (
|
||||
if (*ptr == QSE_MT('-')) *ptr = '_';
|
||||
}
|
||||
|
||||
/* insert the last value only */
|
||||
while (val->next) val = val->next;
|
||||
ret = qse_env_insertmbs (hdrctx->env, http_key, val->ptr);
|
||||
if (ret <= -1)
|
||||
{
|
||||
@ -149,8 +145,18 @@ static int cgi_capture_client_header (
|
||||
hdrctx->httpd->errnum = QSE_HTTPD_ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
QSE_MMGR_FREE (req->mmgr, http_key);
|
||||
|
||||
/* append values with the same key */
|
||||
while ((val = val->next))
|
||||
{
|
||||
if (qse_env_appendmbs (hdrctx->env, QSE_MT(", ")) <= -1 ||
|
||||
qse_env_appendmbs (hdrctx->env, val->ptr) <= -1)
|
||||
{
|
||||
hdrctx->httpd->errnum = QSE_HTTPD_ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -442,19 +448,20 @@ static int cgi_add_env (
|
||||
qparam = qse_htre_getqparam(req);
|
||||
|
||||
#ifdef _WIN32
|
||||
qse_env_insert (env, QSE_T("PATH"), QSE_NULL);
|
||||
if (qse_env_insert (env, QSE_T("PATH"), QSE_NULL) <= -1) goto oops_nomem;
|
||||
#else
|
||||
qse_env_insertmbs (env, QSE_MT("LANG"), QSE_NULL);
|
||||
qse_env_insertmbs (env, QSE_MT("PATH"), QSE_NULL);
|
||||
if (qse_env_insertmbs (env, QSE_MT("LANG"), QSE_NULL) <= -1 ||
|
||||
qse_env_insertmbs (env, QSE_MT("PATH"), QSE_NULL)) goto oops_nomem;
|
||||
#endif
|
||||
|
||||
qse_env_insertmbs (env, QSE_MT("GATEWAY_INTERFACE"), QSE_MT("CGI/1.1"));
|
||||
if (qse_env_insertmbs (env, QSE_MT("GATEWAY_INTERFACE"), QSE_MT("CGI/1.1")) <= -1) goto oops_nomem;
|
||||
qse_mbsxfmt (buf, QSE_COUNTOF(buf), QSE_MT("HTTP/%d.%d"), (int)v->major, (int)v->minor);
|
||||
qse_env_insertmbs (env, QSE_MT("SERVER_PROTOCOL"), buf);
|
||||
if (qse_env_insertmbs (env, QSE_MT("SERVER_PROTOCOL"), buf) <= -1) goto oops_nomem;
|
||||
|
||||
if (qse_env_insertmbs (env, QSE_MT("SCRIPT_FILENAME"), path) <= -1 ||
|
||||
qse_env_insertmbs (env, QSE_MT("SCRIPT_NAME"), script) <= -1 ||
|
||||
qse_env_insertmbs (env, QSE_MT("DOCUMENT_ROOT"), root) <= -1) goto oops_nomem;
|
||||
|
||||
qse_env_insertmbs (env, QSE_MT("SCRIPT_FILENAME"), path);
|
||||
qse_env_insertmbs (env, QSE_MT("SCRIPT_NAME"), script);
|
||||
qse_env_insertmbs (env, QSE_MT("DOCUMENT_ROOT"), root);
|
||||
if (suffix && suffix[0] != QSE_MT('\0'))
|
||||
{
|
||||
const qse_mchar_t* tmp[3];
|
||||
@ -468,40 +475,50 @@ static int cgi_add_env (
|
||||
if (tr)
|
||||
{
|
||||
qse_canonmbspath (tr, tr, 0);
|
||||
qse_env_insertmbs (env, QSE_MT("PATH_TRANSLATED"), tr);
|
||||
if (qse_env_insertmbs (env, QSE_MT("PATH_TRANSLATED"), tr) <= -1)
|
||||
{
|
||||
QSE_MMGR_FREE (httpd->mmgr, tr);
|
||||
goto oops_nomem;
|
||||
}
|
||||
QSE_MMGR_FREE (httpd->mmgr, tr);
|
||||
}
|
||||
qse_env_insertmbs (env, QSE_MT("PATH_INFO"), suffix);
|
||||
if (qse_env_insertmbs (env, QSE_MT("PATH_INFO"), suffix) <= -1) goto oops_nomem;
|
||||
}
|
||||
|
||||
qse_env_insertmbs (env, QSE_MT("REQUEST_METHOD"), qse_htre_getqmethodname(req));
|
||||
qse_env_insertmbs (env, QSE_MT("REQUEST_URI"), qse_htre_getqpath(req));
|
||||
if (qparam) qse_env_insertmbs (env, QSE_MT("QUERY_STRING"), qparam);
|
||||
if (qse_env_insertmbs (env, QSE_MT("REQUEST_METHOD"), qse_htre_getqmethodname(req)) <= -1 ||
|
||||
qse_env_insertmbs (env, QSE_MT("REQUEST_URI"), qse_htre_getqpath(req)) <= -1) goto oops_nomem;
|
||||
|
||||
if (qparam && qse_env_insertmbs (env, QSE_MT("QUERY_STRING"), qparam) <= -1) goto oops_nomem;
|
||||
|
||||
qse_fmtuintmaxtombs (buf, QSE_COUNTOF(buf), content_length, 10, -1, QSE_MT('\0'), QSE_NULL);
|
||||
qse_env_insertmbs (env, QSE_MT("CONTENT_LENGTH"), buf);
|
||||
if (content_type) qse_env_insertmbs (env, QSE_MT("CONTENT_TYPE"), content_type);
|
||||
if (qse_env_insertmbs (env, QSE_MT("CONTENT_LENGTH"), buf) <= -1) goto oops_nomem;
|
||||
if (content_type && qse_env_insertmbs (env, QSE_MT("CONTENT_TYPE"), content_type) <= -1) goto oops_nomem;
|
||||
|
||||
if (chunked) qse_env_insertmbs (env, QSE_MT("TRANSFER_ENCODING"), QSE_MT("chunked"));
|
||||
if (chunked && qse_env_insertmbs (env, QSE_MT("TRANSFER_ENCODING"), QSE_MT("chunked")) <= 1) goto oops_nomem;
|
||||
|
||||
qse_env_insertmbs (env, "SERVER_SOFTWARE", qse_httpd_getname(httpd));
|
||||
if (qse_env_insertmbs (env, "SERVER_SOFTWARE", qse_httpd_getname(httpd)) <= -1) goto oops_nomem;
|
||||
qse_nwadtombs (&client->local_addr, buf, QSE_COUNTOF(buf), QSE_NWADTOMBS_PORT);
|
||||
qse_env_insertmbs (env, QSE_MT("SERVER_PORT"), buf);
|
||||
if (qse_env_insertmbs (env, QSE_MT("SERVER_PORT"), buf) <= -1) goto oops_nomem;
|
||||
qse_nwadtombs (&client->local_addr, buf, QSE_COUNTOF(buf), QSE_NWADTOMBS_ADDR);
|
||||
qse_env_insertmbs (env, QSE_MT("SERVER_ADDR"), buf);
|
||||
qse_env_insertmbs (env, QSE_MT("SERVER_NAME"), buf); /* TODO: convert it to a host name */
|
||||
if (qse_env_insertmbs (env, QSE_MT("SERVER_ADDR"), buf) <= -1) goto oops_nomem;
|
||||
if (qse_env_insertmbs (env, QSE_MT("SERVER_NAME"), buf) <= -1) goto oops_nomem; /* TODO: convert it to a host name */
|
||||
|
||||
qse_nwadtombs (&client->remote_addr, buf, QSE_COUNTOF(buf), QSE_NWADTOMBS_PORT);
|
||||
qse_env_insertmbs (env, QSE_MT("REMOTE_PORT"), buf);
|
||||
if (qse_env_insertmbs (env, QSE_MT("REMOTE_PORT"), buf) <= -1) goto oops_nomem;
|
||||
qse_nwadtombs (&client->remote_addr, buf, QSE_COUNTOF(buf), QSE_NWADTOMBS_ADDR);
|
||||
qse_env_insertmbs (env, QSE_MT("REMOTE_ADDR"), buf);
|
||||
if (qse_env_insertmbs (env, QSE_MT("REMOTE_ADDR"), buf) <= -1) goto oops_nomem;
|
||||
|
||||
ctx.httpd = httpd;
|
||||
ctx.env = env;
|
||||
if (qse_htre_walkheaders (req, cgi_capture_client_header, &ctx) <= -1) return -1;
|
||||
if (qse_htre_walktrailers (req, cgi_capture_client_header, &ctx) <= -1) return -1;
|
||||
if (qse_htre_walkheaders (req, cgi_capture_client_header, &ctx) <= -1 ||
|
||||
qse_htre_walktrailers (req, cgi_capture_client_header, &ctx) <= -1) goto oops;
|
||||
|
||||
return 0;
|
||||
|
||||
oops_nomem:
|
||||
httpd->errnum = QSE_HTTPD_ENOMEM;
|
||||
oops:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int cgi_snatch_client_input (
|
||||
|
@ -201,6 +201,7 @@ static int proxy_capture_peer_header (qse_htre_t* req, const qse_mchar_t* key, c
|
||||
{
|
||||
task_proxy_t* proxy = (task_proxy_t*)ctx;
|
||||
|
||||
#if 0
|
||||
if (!(proxy->httpd->opt.trait & QSE_HTTPD_PROXYNOVIA) && !(proxy->flags & PROXY_VIA_RETURNING))
|
||||
{
|
||||
if (qse_mbscasecmp (key, QSE_MT("Via")) == 0)
|
||||
@ -229,6 +230,7 @@ static int proxy_capture_peer_header (qse_htre_t* req, const qse_mchar_t* key, c
|
||||
qse_httpd_getname(proxy->httpd));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (qse_mbscasecmp (key, QSE_MT("Connection")) != 0 &&
|
||||
qse_mbscasecmp (key, QSE_MT("Transfer-Encoding")) != 0)
|
||||
@ -258,9 +260,9 @@ static int proxy_capture_client_header (qse_htre_t* req, const qse_mchar_t* key,
|
||||
task_proxy_t* proxy = (task_proxy_t*)ctx;
|
||||
|
||||
#if 0
|
||||
if (!(proxy->flags & (PROXY_TRANSPARENT | PROXY_X_FORWARDED_FOR)))
|
||||
if (!(proxy->flags & PROXY_TRANSPARENT))
|
||||
{
|
||||
if (qse_mbscasecmp (key, QSE_MT("X-Forwarded-For")) == 0)
|
||||
if (!(proxy->flags & PROXY_X_FORWARDED_FOR) && qse_mbscasecmp (key, QSE_MT("X-Forwarded-For")) == 0)
|
||||
{
|
||||
/* append to X-Forwarded-For if it exists in the header.
|
||||
* note that it add a comma even if the existing value is empty.
|
||||
@ -274,7 +276,7 @@ static int proxy_capture_client_header (qse_htre_t* req, const qse_mchar_t* key,
|
||||
return proxy_add_header_to_buffer_with_extra_data (proxy, proxy->reqfwdbuf, key, val, QSE_MT(", %hs"), extra);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if (!(proxy->httpd->opt.trait & QSE_HTTPD_PROXYNOVIA) && !(proxy->flags & PROXY_VIA))
|
||||
{
|
||||
@ -303,6 +305,7 @@ static int proxy_capture_client_header (qse_htre_t* req, const qse_mchar_t* key,
|
||||
qse_httpd_getname(proxy->httpd));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* EXPERIMENTAL: REMOVE HEADERS.
|
||||
* FOR EXAMPLE, You can remove Referer or forge it to give analysis systems harder time */
|
||||
@ -1145,6 +1148,9 @@ qse_mbs_ncat (proxy->reqfwdbuf, spc, QSE_COUNTOF(spc));
|
||||
if (qse_mbs_cat (proxy->reqfwdbuf, QSE_MT("X-Forwarded-Proto: ")) == (qse_size_t)-1 ||
|
||||
qse_mbs_cat (proxy->reqfwdbuf, ((client->status & QSE_HTTPD_CLIENT_SECURE)? QSE_MT("https"): QSE_MT("http"))) == (qse_size_t)-1 ||
|
||||
qse_mbs_cat (proxy->reqfwdbuf, QSE_MT("\r\n")) == (qse_size_t)-1) goto nomem_oops;
|
||||
|
||||
/* TODO: support the Forwarded header in RFC7239.
|
||||
* Forwarded: for=xxx;by=xxx;prot=xxxx */
|
||||
}
|
||||
|
||||
proxy->resflags |= PROXY_RES_AWAIT_RESHDR;
|
||||
|
Reference in New Issue
Block a user