improved cgi and proxy handling
This commit is contained in:
parent
45b7832b99
commit
897bd1348d
@ -1263,7 +1263,7 @@ struct task_cgi_t
|
|||||||
|
|
||||||
#define CGI_RES_CLIENT_DISCON (1 << 0)
|
#define CGI_RES_CLIENT_DISCON (1 << 0)
|
||||||
#define CGI_RES_CLIENT_CHUNK (1 << 1)
|
#define CGI_RES_CLIENT_CHUNK (1 << 1)
|
||||||
#define CGI_RES_SCRIPT_OUTPUT_LENGTH (1 << 2)
|
#define CGI_RES_SCRIPT_LENGTH (1 << 2)
|
||||||
int resflags;
|
int resflags;
|
||||||
qse_mbs_t* res;
|
qse_mbs_t* res;
|
||||||
qse_mchar_t* res_ptr;
|
qse_mchar_t* res_ptr;
|
||||||
@ -1324,10 +1324,14 @@ static int cgi_capture_script_header (qse_htre_t* req, const qse_mchar_t* key, c
|
|||||||
qse_mbscmp (key, QSE_MT("Connection")) != 0 &&
|
qse_mbscmp (key, QSE_MT("Connection")) != 0 &&
|
||||||
qse_mbscmp (key, QSE_MT("Transfer-Encoding")) != 0)
|
qse_mbscmp (key, QSE_MT("Transfer-Encoding")) != 0)
|
||||||
{
|
{
|
||||||
if (qse_mbs_cat (cgi->res, key) == (qse_size_t)-1) return -1;
|
if (qse_mbs_cat (cgi->res, key) == (qse_size_t)-1 ||
|
||||||
if (qse_mbs_cat (cgi->res, QSE_MT(": ")) == (qse_size_t)-1) return -1;
|
qse_mbs_cat (cgi->res, QSE_MT(": ")) == (qse_size_t)-1 ||
|
||||||
if (qse_mbs_cat (cgi->res, val) == (qse_size_t)-1) return -1;
|
qse_mbs_cat (cgi->res, val) == (qse_size_t)-1 ||
|
||||||
if (qse_mbs_cat (cgi->res, QSE_MT("\r\n")) == (qse_size_t)-1) return -1;
|
qse_mbs_cat (cgi->res, QSE_MT("\r\n")) == (qse_size_t)-1)
|
||||||
|
{
|
||||||
|
cgi->httpd->errnum = QSE_HTTPD_ENOMEM;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1412,7 +1416,7 @@ static int cgi_htrd_peek_script_output (qse_htrd_t* htrd, qse_htre_t* req)
|
|||||||
keepalive = cgi->keepalive;
|
keepalive = cgi->keepalive;
|
||||||
if (req->attr.content_length_set)
|
if (req->attr.content_length_set)
|
||||||
{
|
{
|
||||||
cgi->resflags |= CGI_RES_SCRIPT_OUTPUT_LENGTH;
|
cgi->resflags |= CGI_RES_SCRIPT_LENGTH;
|
||||||
cgi->script_output_length = req->attr.content_length;
|
cgi->script_output_length = req->attr.content_length;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1466,7 +1470,7 @@ static int cgi_htrd_peek_script_output (qse_htrd_t* htrd, qse_htre_t* req)
|
|||||||
|
|
||||||
/* content body begins here */
|
/* content body begins here */
|
||||||
cgi->script_output_received = qse_htre_getcontentlen(req);
|
cgi->script_output_received = qse_htre_getcontentlen(req);
|
||||||
if ((cgi->resflags & CGI_RES_SCRIPT_OUTPUT_LENGTH) &&
|
if ((cgi->resflags & CGI_RES_SCRIPT_LENGTH) &&
|
||||||
cgi->script_output_received > cgi->script_output_length)
|
cgi->script_output_received > cgi->script_output_length)
|
||||||
{
|
{
|
||||||
/* TODO: cgi returning too much data... something is wrong in CGI */
|
/* TODO: cgi returning too much data... something is wrong in CGI */
|
||||||
@ -1658,7 +1662,9 @@ else qse_printf (QSE_T("!!!CGI SNATCHING DONE\n"));
|
|||||||
/* mark the there's nothing to read form the client side */
|
/* mark the there's nothing to read form the client side */
|
||||||
cgi->reqflags |= CGI_REQ_GOTALL;
|
cgi->reqflags |= CGI_REQ_GOTALL;
|
||||||
|
|
||||||
/* this request object can be reused regardless of this task */
|
/* deregister the callback so that data fed to this
|
||||||
|
* request object before the current task terminats
|
||||||
|
* doesn't trigger this callback. */
|
||||||
qse_htre_unsetconcb (cgi->req);
|
qse_htre_unsetconcb (cgi->req);
|
||||||
cgi->req = QSE_NULL;
|
cgi->req = QSE_NULL;
|
||||||
|
|
||||||
@ -1684,6 +1690,7 @@ else qse_printf (QSE_T("!!!CGI SNATCHING DONE\n"));
|
|||||||
* error. if an error occurred, we simply drop the data. */
|
* error. if an error occurred, we simply drop the data. */
|
||||||
if (qse_mbs_ncat (cgi->reqfwdbuf, ptr, len) == (qse_size_t)-1)
|
if (qse_mbs_ncat (cgi->reqfwdbuf, ptr, len) == (qse_size_t)-1)
|
||||||
{
|
{
|
||||||
|
cgi->httpd->errnum = QSE_HTTPD_ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
qse_printf (QSE_T("!!!CGI SNATCHED [%.*hs]\n"), len, ptr);
|
qse_printf (QSE_T("!!!CGI SNATCHED [%.*hs]\n"), len, ptr);
|
||||||
@ -1762,15 +1769,16 @@ qse_printf (QSE_T("FORWARD: @@@@@@@@WRITE TO CGI FAILED\n"));
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!(cgi->reqflags & CGI_REQ_GOTALL))
|
else if (cgi->reqflags & CGI_REQ_GOTALL)
|
||||||
{
|
{
|
||||||
/* there is nothing to read from the client side and
|
/* there is nothing to read from the client side and
|
||||||
* there is nothing more to forward in the forwarding buffer.
|
* there is nothing more to forward in the forwarding buffer.
|
||||||
* clear the relay and write triggers.
|
* clear the relay and write triggers for the time being.
|
||||||
*/
|
*/
|
||||||
qse_printf (QSE_T("FORWARD: @@@@@@@@NOTHING MORE TO WRITE TO CGI\n"));
|
qse_printf (QSE_T("FORWARD: @@@@@@@@NOTHING MORE TO WRITE TO CGI\n"));
|
||||||
task->trigger[1].mask = 0;
|
QSE_ASSERT (cgi->req == QSE_NULL);
|
||||||
task->trigger[2].mask = 0;
|
task->trigger[1].mask = 0; /* pipe output to child */
|
||||||
|
task->trigger[2].mask = 0; /* client-side */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2117,7 +2125,7 @@ qse_printf (QSE_T("TASK_MAIN_CGI_4\n"));
|
|||||||
|
|
||||||
cgi->script_output_received += n;
|
cgi->script_output_received += n;
|
||||||
|
|
||||||
if ((cgi->resflags & CGI_RES_SCRIPT_OUTPUT_LENGTH) &&
|
if ((cgi->resflags & CGI_RES_SCRIPT_LENGTH) &&
|
||||||
cgi->script_output_received > cgi->script_output_length)
|
cgi->script_output_received > cgi->script_output_length)
|
||||||
{
|
{
|
||||||
/* TODO: cgi returning too much data... something is wrong in CGI */
|
/* TODO: cgi returning too much data... something is wrong in CGI */
|
||||||
@ -2143,7 +2151,7 @@ qse_printf (QSE_T("TASK_MAIN_CGI_4\n"));
|
|||||||
}
|
}
|
||||||
|
|
||||||
cgi->script_output_received += n;
|
cgi->script_output_received += n;
|
||||||
if ((cgi->resflags & CGI_RES_SCRIPT_OUTPUT_LENGTH) &&
|
if ((cgi->resflags & CGI_RES_SCRIPT_LENGTH) &&
|
||||||
cgi->script_output_received > cgi->script_output_length)
|
cgi->script_output_received > cgi->script_output_length)
|
||||||
{
|
{
|
||||||
/* TODO: logging */
|
/* TODO: logging */
|
||||||
@ -2217,7 +2225,7 @@ qse_printf (QSE_T("[cgi-3 send failure....\n"));
|
|||||||
{
|
{
|
||||||
qse_mbs_clear (cgi->res);
|
qse_mbs_clear (cgi->res);
|
||||||
|
|
||||||
if ((cgi->resflags & CGI_RES_SCRIPT_OUTPUT_LENGTH) &&
|
if ((cgi->resflags & CGI_RES_SCRIPT_LENGTH) &&
|
||||||
cgi->script_output_received >= cgi->script_output_length)
|
cgi->script_output_received >= cgi->script_output_length)
|
||||||
{
|
{
|
||||||
qse_printf (QSE_T("[switching to cgi-5....\n"));
|
qse_printf (QSE_T("[switching to cgi-5....\n"));
|
||||||
@ -2546,23 +2554,23 @@ struct task_proxy_t
|
|||||||
qse_mbs_t* res;
|
qse_mbs_t* res;
|
||||||
qse_size_t res_consumed;
|
qse_size_t res_consumed;
|
||||||
qse_size_t res_pending;
|
qse_size_t res_pending;
|
||||||
|
#define PROXY_RES_CLIENT_DISCON (1 << 0) /* disconnect client after task */
|
||||||
#define AWAIT_100 (1 << 0)
|
#define PROXY_RES_CLIENT_CHUNK (1 << 1) /* chunk chunked output to client */
|
||||||
#define AWAIT_RES (1 << 1)
|
#define PROXY_RES_PEER_CLOSE (1 << 2) /* read peer until close.
|
||||||
#define AWAIT_CON (1 << 2)
|
* no chunk nor no size specified */
|
||||||
#define RECEIVED_100 (1 << 3)
|
#define PROXY_RES_PEER_CHUNK (1 << 4) /* peer's output is chunked */
|
||||||
#define RECEIVED_RES (1 << 4)
|
#define PROXY_RES_PEER_LENGTH (1 << 5) /* peer's output is set with
|
||||||
#define RECEIVED_CON (1 << 5)
|
* the content-length */
|
||||||
int expect_100;
|
#define PROXY_RES_AWAIT_100 (1 << 10) /* waiting for 100 continue */
|
||||||
|
#define PROXY_RES_AWAIT_RESHDR (1 << 11) /* waiting for response header */
|
||||||
#define PROXY_RES_CLIENT_DISCON (1 << 0)
|
#define PROXY_RES_AWAIT_RESCON (1 << 12) /* waiting for response content.
|
||||||
#define PROXY_RES_CLIENT_CHUNK (1 << 1)
|
* used iif PROXY_RES_CLIENT_CHUNK
|
||||||
|
* is on */
|
||||||
#define PROXY_RES_PEER_CLOSE (1 << 2) /* read until close */
|
#define PROXY_RES_RECEIVED_100 (1 << 13) /* got 100 continue */
|
||||||
#define PROXY_RES_PEER_CLOSED (1 << 3)
|
#define PROXY_RES_RECEIVED_RESHDR (1 << 14) /* got response header at least */
|
||||||
|
#define PROXY_RES_RECEIVED_RESCON (1 << 15) /* finished getting the response
|
||||||
#define PROXY_RES_PEER_CHUNK (1 << 4)
|
* content fully. used iif
|
||||||
#define PROXY_RES_PEER_OUTPUT_LENGTH (1 << 6) /* content-length is set */
|
* PROXY_RES_CLIENT_CHUNK is on */
|
||||||
int resflags;
|
int resflags;
|
||||||
|
|
||||||
qse_size_t peer_output_length;
|
qse_size_t peer_output_length;
|
||||||
@ -2630,6 +2638,7 @@ else qse_printf (QSE_T("!!!PROXY SNATCHING DONE\n"));
|
|||||||
* error. if an error occurred, we simply drop the data. */
|
* error. if an error occurred, we simply drop the data. */
|
||||||
if (qse_mbs_ncat (proxy->reqfwdbuf, ptr, len) == (qse_size_t)-1)
|
if (qse_mbs_ncat (proxy->reqfwdbuf, ptr, len) == (qse_size_t)-1)
|
||||||
{
|
{
|
||||||
|
proxy->httpd->errnum = QSE_HTTPD_ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
qse_printf (QSE_T("!!!PROXY SNATCHED [%.*hs]\n"), len, ptr);
|
qse_printf (QSE_T("!!!PROXY SNATCHED [%.*hs]\n"), len, ptr);
|
||||||
@ -2650,72 +2659,69 @@ static int proxy_snatch_peer_output (
|
|||||||
task = (qse_httpd_task_t*)ctx;
|
task = (qse_httpd_task_t*)ctx;
|
||||||
proxy = (task_proxy_t*)task->ctx;
|
proxy = (task_proxy_t*)task->ctx;
|
||||||
|
|
||||||
|
/* this callback is enabled if and only if the output back to
|
||||||
|
* the client should be chunked */
|
||||||
QSE_ASSERT (proxy->resflags & PROXY_RES_CLIENT_CHUNK);
|
QSE_ASSERT (proxy->resflags & PROXY_RES_CLIENT_CHUNK);
|
||||||
|
|
||||||
|
|
||||||
|
/* TODO: better condition for compaction??? */
|
||||||
|
if (proxy->res_pending > 0 && proxy->res_consumed > 0)
|
||||||
|
{
|
||||||
|
qse_mbs_del (proxy->res, 0, proxy->res_consumed);
|
||||||
|
proxy->res_consumed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (ptr == QSE_NULL)
|
if (ptr == QSE_NULL)
|
||||||
{
|
{
|
||||||
/* content completed */
|
/* content completed */
|
||||||
|
QSE_ASSERT (len == 0);
|
||||||
|
|
||||||
qse_printf (QSE_T("PROXY GOT ALL RESPONSE>>>>>>>\n"));
|
qse_printf (QSE_T("PROXY GOT ALL RESPONSE>>>>>>>\n"));
|
||||||
if (proxy->resflags & PROXY_RES_CLIENT_CHUNK) /*TODO: remove this check */
|
|
||||||
{
|
|
||||||
qse_printf (QSE_T("ADDING CHUNK END>>>>>>>\n"));
|
|
||||||
if (qse_mbs_cat (proxy->res, QSE_MT("0\r\n\r\n")) == (qse_size_t)-1)
|
if (qse_mbs_cat (proxy->res, QSE_MT("0\r\n\r\n")) == (qse_size_t)-1)
|
||||||
{
|
{
|
||||||
proxy->httpd->errnum = QSE_HTTPD_ENOMEM;
|
proxy->httpd->errnum = QSE_HTTPD_ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: include trailers into proxy->res if any. for this htrd and htre need to be enhanced as well */
|
/* TODO: include trailers into proxy->res if any. for this htrd and htre need to be enhanced as well */
|
||||||
|
|
||||||
proxy->expect_100 &= ~AWAIT_CON;
|
proxy->resflags &= ~PROXY_RES_AWAIT_RESCON;
|
||||||
proxy->expect_100 |= RECEIVED_CON;
|
proxy->resflags |= PROXY_RES_RECEIVED_RESCON;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* append the peer response content to the response buffer */
|
/* append the peer response content to the response buffer */
|
||||||
if (proxy->resflags & PROXY_RES_CLIENT_CHUNK) /* TODO: remove this check */
|
|
||||||
{
|
|
||||||
qse_mchar_t buf[64];
|
qse_mchar_t buf[64];
|
||||||
snprintf (buf, QSE_COUNTOF(buf), QSE_MT("%lX\r\n"), (unsigned long)len);
|
snprintf (buf, QSE_COUNTOF(buf), QSE_MT("%lX\r\n"), (unsigned long)len);
|
||||||
if (qse_mbs_cat (proxy->res, buf) == (qse_size_t)-1)
|
|
||||||
{
|
|
||||||
proxy->httpd->errnum = QSE_HTTPD_ENOMEM;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (qse_mbs_ncat (proxy->res, ptr, len) == (qse_size_t)-1)
|
if (qse_mbs_cat (proxy->res, buf) == (qse_size_t)-1 ||
|
||||||
|
qse_mbs_ncat (proxy->res, ptr, len) == (qse_size_t)-1 ||
|
||||||
|
qse_mbs_cat (proxy->res, QSE_MT("\r\n")) == (qse_size_t)-1)
|
||||||
{
|
{
|
||||||
proxy->httpd->errnum = QSE_HTTPD_ENOMEM;
|
proxy->httpd->errnum = QSE_HTTPD_ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proxy->resflags & PROXY_RES_CLIENT_CHUNK) /* TODO: remove this check */
|
|
||||||
{
|
|
||||||
if (qse_mbs_cat (proxy->res, QSE_MT("\r\n")) == (qse_size_t)-1)
|
|
||||||
{
|
|
||||||
proxy->httpd->errnum = QSE_HTTPD_ENOMEM;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
proxy->res_pending = QSE_MBS_LEN(proxy->res) - proxy->res_consumed;
|
proxy->res_pending = QSE_MBS_LEN(proxy->res) - proxy->res_consumed;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int add_header_to_proxy_resbuf (qse_htre_t* req, const qse_mchar_t* key, const qse_mchar_t* val, void* ctx)
|
static int proxy_capture_peer_header (qse_htre_t* req, const qse_mchar_t* key, const qse_mchar_t* val, void* ctx)
|
||||||
{
|
{
|
||||||
task_proxy_t* proxy = (task_proxy_t*)ctx;
|
task_proxy_t* proxy = (task_proxy_t*)ctx;
|
||||||
|
|
||||||
if (qse_mbscmp (key, QSE_MT("Transfer-Encoding")) != 0)
|
if (qse_mbscmp (key, QSE_MT("Connection")) != 0 &&
|
||||||
|
qse_mbscmp (key, QSE_MT("Transfer-Encoding")) != 0)
|
||||||
{
|
{
|
||||||
if (qse_mbs_cat (proxy->res, key) == (qse_size_t)-1) return -1;
|
if (qse_mbs_cat (proxy->res, key) == (qse_size_t)-1 ||
|
||||||
if (qse_mbs_cat (proxy->res, QSE_MT(": ")) == (qse_size_t)-1) return -1;
|
qse_mbs_cat (proxy->res, QSE_MT(": ")) == (qse_size_t)-1 ||
|
||||||
if (qse_mbs_cat (proxy->res, val) == (qse_size_t)-1) return -1;
|
qse_mbs_cat (proxy->res, val) == (qse_size_t)-1 ||
|
||||||
if (qse_mbs_cat (proxy->res, QSE_MT("\r\n")) == (qse_size_t)-1) return -1;
|
qse_mbs_cat (proxy->res, QSE_MT("\r\n")) == (qse_size_t)-1)
|
||||||
|
{
|
||||||
|
proxy->httpd->errnum = QSE_HTTPD_ENOMEM;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -2729,7 +2735,7 @@ static int proxy_htrd_peek_peer_output (qse_htrd_t* htrd, qse_htre_t* res)
|
|||||||
xtn = (proxy_peer_htrd_xtn_t*) qse_htrd_getxtn (htrd);
|
xtn = (proxy_peer_htrd_xtn_t*) qse_htrd_getxtn (htrd);
|
||||||
proxy = xtn->proxy;
|
proxy = xtn->proxy;
|
||||||
|
|
||||||
if (proxy->expect_100 & RECEIVED_RES)
|
if (proxy->resflags & PROXY_RES_RECEIVED_RESHDR)
|
||||||
{
|
{
|
||||||
/* this peek handler is being called again.
|
/* this peek handler is being called again.
|
||||||
* this can happen if qse_htrd_feed() is fed with
|
* this can happen if qse_htrd_feed() is fed with
|
||||||
@ -2738,12 +2744,12 @@ static int proxy_htrd_peek_peer_output (qse_htrd_t* htrd, qse_htre_t* res)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((proxy->expect_100 & AWAIT_100) && qse_htre_getscodeval(res) == 100)
|
if ((proxy->resflags & PROXY_RES_AWAIT_100) && qse_htre_getscodeval(res) == 100)
|
||||||
{
|
{
|
||||||
/* TODO: check if the request contained Expect... */
|
/* TODO: check if the request contained Expect... */
|
||||||
qse_printf (QSE_T("10000000000000000000000000000 CONTINUE 10000000000000000000000000000000\n"));
|
qse_printf (QSE_T("10000000000000000000000000000 CONTINUE 10000000000000000000000000000000\n"));
|
||||||
proxy->expect_100 &= ~AWAIT_100;
|
proxy->resflags &= ~PROXY_RES_AWAIT_100;
|
||||||
proxy->expect_100 |= RECEIVED_100;
|
proxy->resflags |= PROXY_RES_RECEIVED_100;
|
||||||
|
|
||||||
if (qse_mbs_cat (proxy->res, qse_htre_getverstr(res)) == (qse_size_t)-1) return -1;
|
if (qse_mbs_cat (proxy->res, qse_htre_getverstr(res)) == (qse_size_t)-1) return -1;
|
||||||
if (qse_mbs_cat (proxy->res, QSE_MT(" ")) == (qse_size_t)-1) return -1;;
|
if (qse_mbs_cat (proxy->res, QSE_MT(" ")) == (qse_size_t)-1) return -1;;
|
||||||
@ -2761,9 +2767,9 @@ qse_printf (QSE_T("10000000000000000000000000000 CONTINUE 1000000000000000000000
|
|||||||
int keepalive;
|
int keepalive;
|
||||||
|
|
||||||
/* add initial line and headers to proxy->res */
|
/* add initial line and headers to proxy->res */
|
||||||
proxy->expect_100 &= ~AWAIT_100;
|
proxy->resflags &= ~PROXY_RES_AWAIT_100;
|
||||||
proxy->expect_100 &= ~AWAIT_RES;
|
proxy->resflags &= ~PROXY_RES_AWAIT_RESHDR;
|
||||||
proxy->expect_100 |= RECEIVED_RES;
|
proxy->resflags |= PROXY_RES_RECEIVED_RESHDR;
|
||||||
|
|
||||||
qse_printf (QSE_T("NORMAL REPLY 222222222222222222222 NORMAL REPLY\n"));
|
qse_printf (QSE_T("NORMAL REPLY 222222222222222222222 NORMAL REPLY\n"));
|
||||||
/* begin initial line */
|
/* begin initial line */
|
||||||
@ -2779,7 +2785,7 @@ qse_printf (QSE_T("NORMAL REPLY 222222222222222222222 NORMAL REPLY\n"));
|
|||||||
if (res->attr.content_length_set)
|
if (res->attr.content_length_set)
|
||||||
{
|
{
|
||||||
/* the response from the peer is length based */
|
/* the response from the peer is length based */
|
||||||
proxy->resflags |= PROXY_RES_PEER_OUTPUT_LENGTH;
|
proxy->resflags |= PROXY_RES_PEER_LENGTH;
|
||||||
proxy->peer_output_length = res->attr.content_length;
|
proxy->peer_output_length = res->attr.content_length;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2804,41 +2810,42 @@ qse_printf (QSE_T("NORMAL REPLY 222222222222222222222 NORMAL REPLY\n"));
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* no chunk, no size */
|
/* no chunk, no size. i should read
|
||||||
|
* the peer's output until it closes connection */
|
||||||
proxy->resflags |= PROXY_RES_PEER_CLOSE;
|
proxy->resflags |= PROXY_RES_PEER_CLOSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* client doesn't support chunking */
|
/* client doesn't support chunking */
|
||||||
|
keepalive = 0;
|
||||||
proxy->resflags |= PROXY_RES_CLIENT_DISCON;
|
proxy->resflags |= PROXY_RES_CLIENT_DISCON;
|
||||||
if (qse_httpd_entaskdisconnect (proxy->httpd, xtn->client, xtn->task) == QSE_NULL) return -1;
|
if (qse_httpd_entaskdisconnect (proxy->httpd, xtn->client, xtn->task) == QSE_NULL) return -1;
|
||||||
|
|
||||||
if (res->attr.chunked)
|
if (res->attr.chunked)
|
||||||
{
|
|
||||||
proxy->resflags |= PROXY_RES_PEER_CHUNK;
|
proxy->resflags |= PROXY_RES_PEER_CHUNK;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
/* read peer until it closes */
|
|
||||||
proxy->resflags |= PROXY_RES_PEER_CLOSE;
|
proxy->resflags |= PROXY_RES_PEER_CLOSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (qse_mbs_cat (proxy->res, (keepalive? QSE_MT("Connection: keep-alive\r\n"): QSE_MT("Connection: close\r\n"))) == (qse_size_t)-1)
|
||||||
|
{
|
||||||
|
proxy->httpd->errnum = QSE_HTTPD_ENOMEM;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: add Conntion here like in cgi handler??? depending on keepalive??? */
|
if (qse_htre_walkheaders (res, proxy_capture_peer_header, proxy) <= -1) return -1;
|
||||||
|
|
||||||
if (qse_htre_walkheaders (res, add_header_to_proxy_resbuf, proxy) <= -1) return -1;
|
|
||||||
/* end of headers */
|
/* end of headers */
|
||||||
if (qse_mbs_cat (proxy->res, QSE_MT("\r\n")) == (qse_size_t)-1) return -1;
|
if (qse_mbs_cat (proxy->res, QSE_MT("\r\n")) == (qse_size_t)-1) return -1;
|
||||||
|
|
||||||
|
|
||||||
/* content body begins here */
|
/* content body begins here */
|
||||||
proxy->peer_output_received = qse_htre_getcontentlen(res);
|
proxy->peer_output_received = qse_htre_getcontentlen(res);
|
||||||
if ((proxy->resflags & PROXY_RES_PEER_OUTPUT_LENGTH) &&
|
if ((proxy->resflags & PROXY_RES_PEER_LENGTH) &&
|
||||||
proxy->peer_output_received > proxy->peer_output_length)
|
proxy->peer_output_received > proxy->peer_output_length)
|
||||||
{
|
{
|
||||||
/* TODO: proxy returning too much data... something is wrong in CGI */
|
/* TODO: logging?? */
|
||||||
qse_printf (QSE_T("PROXY PEER FUCKED - RETURNING TOO MUCH...\n"));
|
qse_printf (QSE_T("PROXY PEER FUCKED - RETURNING TOO MUCH...\n"));
|
||||||
proxy->httpd->errnum = QSE_HTTPD_EINVAL; /* TODO: change it to a better error code */
|
proxy->httpd->errnum = QSE_HTTPD_EINVAL; /* TODO: change it to a better error code */
|
||||||
return -1;
|
return -1;
|
||||||
@ -2853,26 +2860,21 @@ qse_printf (QSE_T("PROXY PEER FUCKED - RETURNING TOO MUCH...\n"));
|
|||||||
{
|
{
|
||||||
qse_mchar_t buf[64];
|
qse_mchar_t buf[64];
|
||||||
snprintf (buf, QSE_COUNTOF(buf), QSE_MT("%lX\r\n"), (unsigned long)proxy->peer_output_received);
|
snprintf (buf, QSE_COUNTOF(buf), QSE_MT("%lX\r\n"), (unsigned long)proxy->peer_output_received);
|
||||||
if (qse_mbs_cat (proxy->res, buf) == (qse_size_t)-1)
|
if (qse_mbs_cat (proxy->res, buf) == (qse_size_t)-1 ||
|
||||||
|
qse_mbs_ncat (proxy->res, qse_htre_getcontentptr(res), qse_htre_getcontentlen(res)) == (qse_size_t)-1 ||
|
||||||
|
qse_mbs_ncat (proxy->res, QSE_MT("\r\n"), 2) == (qse_size_t)-1)
|
||||||
{
|
{
|
||||||
proxy->httpd->errnum = QSE_HTTPD_ENOMEM;
|
proxy->httpd->errnum = QSE_HTTPD_ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (qse_mbs_ncat (proxy->res, qse_htre_getcontentptr(res), qse_htre_getcontentlen(res)) == (qse_size_t)-1)
|
if (qse_mbs_ncat (proxy->res, qse_htre_getcontentptr(res), qse_htre_getcontentlen(res)) == (qse_size_t)-1)
|
||||||
{
|
{
|
||||||
proxy->httpd->errnum = QSE_HTTPD_ENOMEM;
|
proxy->httpd->errnum = QSE_HTTPD_ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proxy->resflags & PROXY_RES_CLIENT_CHUNK)
|
|
||||||
{
|
|
||||||
if (qse_mbs_ncat (proxy->res, QSE_MT("\r\n"), 2) == (qse_size_t)-1)
|
|
||||||
{
|
|
||||||
proxy->httpd->errnum = QSE_HTTPD_ENOMEM;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3027,14 +3029,14 @@ len = 1024;
|
|||||||
if (qse_htre_walkheaders (arg->req, add_header_to_proxy_fwdbuf, proxy) <= -1) goto oops;
|
if (qse_htre_walkheaders (arg->req, add_header_to_proxy_fwdbuf, proxy) <= -1) goto oops;
|
||||||
if (qse_mbs_cat (proxy->reqfwdbuf, QSE_MT("\r\n")) == (qse_size_t)-1) goto oops;
|
if (qse_mbs_cat (proxy->reqfwdbuf, QSE_MT("\r\n")) == (qse_size_t)-1) goto oops;
|
||||||
|
|
||||||
proxy->expect_100 |= AWAIT_RES;
|
proxy->resflags |= PROXY_RES_AWAIT_RESHDR;
|
||||||
if (arg->req->attr.expect &&
|
if (arg->req->attr.expect &&
|
||||||
(arg->req->version.major > 1 ||
|
(arg->req->version.major > 1 ||
|
||||||
(arg->req->version.major == 1 && arg->req->version.minor >= 1)))
|
(arg->req->version.major == 1 && arg->req->version.minor >= 1)))
|
||||||
{
|
{
|
||||||
if (qse_mbscasecmp(arg->req->attr.expect, QSE_MT("100-continue")) == 0)
|
if (qse_mbscasecmp(arg->req->attr.expect, QSE_MT("100-continue")) == 0)
|
||||||
{
|
{
|
||||||
proxy->expect_100 |= AWAIT_100;
|
proxy->resflags |= PROXY_RES_AWAIT_100;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3221,7 +3223,7 @@ qse_printf (QSE_T("task_main_proxy_4 read from PEER...%d\n"), (int)n);
|
|||||||
}
|
}
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
{
|
{
|
||||||
if (proxy->resflags & PROXY_RES_PEER_OUTPUT_LENGTH)
|
if (proxy->resflags & PROXY_RES_PEER_LENGTH)
|
||||||
{
|
{
|
||||||
if (proxy->peer_output_received < proxy->peer_output_length)
|
if (proxy->peer_output_received < proxy->peer_output_length)
|
||||||
{
|
{
|
||||||
@ -3239,7 +3241,7 @@ qse_printf (QSE_T("task_main_proxy_4 read from PEER...%d\n"), (int)n);
|
|||||||
proxy->buflen += n;
|
proxy->buflen += n;
|
||||||
proxy->peer_output_received += n;
|
proxy->peer_output_received += n;
|
||||||
|
|
||||||
if (proxy->resflags & PROXY_RES_PEER_OUTPUT_LENGTH)
|
if (proxy->resflags & PROXY_RES_PEER_LENGTH)
|
||||||
{
|
{
|
||||||
if (proxy->peer_output_received > proxy->peer_output_length)
|
if (proxy->peer_output_received > proxy->peer_output_length)
|
||||||
{
|
{
|
||||||
@ -3332,7 +3334,7 @@ qse_printf (QSE_T("[proxy-3 send failure....\n"));
|
|||||||
qse_mbs_clear (proxy->res);
|
qse_mbs_clear (proxy->res);
|
||||||
|
|
||||||
if ((proxy->resflags & PROXY_RES_CLIENT_CHUNK) ||
|
if ((proxy->resflags & PROXY_RES_CLIENT_CHUNK) ||
|
||||||
((proxy->resflags & PROXY_RES_PEER_OUTPUT_LENGTH) && proxy->peer_output_received >= proxy->peer_output_length))
|
((proxy->resflags & PROXY_RES_PEER_LENGTH) && proxy->peer_output_received >= proxy->peer_output_length))
|
||||||
{
|
{
|
||||||
task->main = task_main_proxy_5;
|
task->main = task_main_proxy_5;
|
||||||
task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
@ -3381,7 +3383,7 @@ static int task_main_proxy_2 (
|
|||||||
qse_ssize_t n;
|
qse_ssize_t n;
|
||||||
qse_size_t count;
|
qse_size_t count;
|
||||||
|
|
||||||
QSE_ASSERT ((proxy->expect_100 & AWAIT_RES) || (proxy->resflags & PROXY_RES_CLIENT_CHUNK));
|
QSE_ASSERT ((proxy->resflags & PROXY_RES_AWAIT_RESHDR) || (proxy->resflags & PROXY_RES_CLIENT_CHUNK));
|
||||||
|
|
||||||
count = proxy->res_pending;
|
count = proxy->res_pending;
|
||||||
if (count > MAX_SEND_SIZE) count = MAX_SEND_SIZE;
|
if (count > MAX_SEND_SIZE) count = MAX_SEND_SIZE;
|
||||||
@ -3432,13 +3434,13 @@ qse_printf (QSE_T("[proxy-2 send failure....\n"));
|
|||||||
}
|
}
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
{
|
{
|
||||||
if (!(proxy->expect_100 & RECEIVED_RES))
|
if (!(proxy->resflags & PROXY_RES_RECEIVED_RESHDR))
|
||||||
{
|
{
|
||||||
/* end of output from peer before it has seen a header.
|
/* end of output from peer before it has seen a header.
|
||||||
* the proxy script must be crooked. */
|
* the proxy script must be crooked. */
|
||||||
/* TODO: logging */
|
/* TODO: logging */
|
||||||
qse_printf (QSE_T("#####PREMATURE EOF FROM PEER\n"));
|
qse_printf (QSE_T("#####PREMATURE EOF FROM PEER\n"));
|
||||||
if (!(proxy->expect_100 & RECEIVED_100))
|
if (!(proxy->resflags & PROXY_RES_RECEIVED_100))
|
||||||
{
|
{
|
||||||
http_errnum = 502;
|
http_errnum = 502;
|
||||||
goto oops;
|
goto oops;
|
||||||
@ -3480,25 +3482,25 @@ qse_printf (QSE_T("#####INVALID HEADER FROM PEER [%.*hs]\n"), (int)proxy->buflen
|
|||||||
|
|
||||||
if (QSE_MBS_LEN(proxy->res) > 0)
|
if (QSE_MBS_LEN(proxy->res) > 0)
|
||||||
{
|
{
|
||||||
if (proxy->expect_100 & RECEIVED_CON)
|
if (proxy->resflags & PROXY_RES_RECEIVED_RESCON)
|
||||||
{
|
{
|
||||||
QSE_ASSERT (proxy->resflags & PROXY_RES_CLIENT_CHUNK);
|
QSE_ASSERT (proxy->resflags & PROXY_RES_CLIENT_CHUNK);
|
||||||
task->main = task_main_proxy_3;
|
task->main = task_main_proxy_3;
|
||||||
task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
}
|
}
|
||||||
else if (proxy->expect_100 & AWAIT_CON)
|
else if (proxy->resflags & PROXY_RES_AWAIT_RESCON)
|
||||||
{
|
{
|
||||||
QSE_ASSERT (proxy->resflags & PROXY_RES_CLIENT_CHUNK);
|
QSE_ASSERT (proxy->resflags & PROXY_RES_CLIENT_CHUNK);
|
||||||
task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
}
|
}
|
||||||
else if (proxy->expect_100 & RECEIVED_RES)
|
else if (proxy->resflags & PROXY_RES_RECEIVED_RESHDR)
|
||||||
{
|
{
|
||||||
/* the actual response header has been received
|
/* the actual response header has been received
|
||||||
* with or without '100 continue'. you can
|
* with or without '100 continue'. you can
|
||||||
* check it with proxy->expect_100 & RECEIVED_100 */
|
* check it with proxy->resflags & PROXY_RES_RECEIVED_100 */
|
||||||
if (proxy->resflags & PROXY_RES_CLIENT_CHUNK)
|
if (proxy->resflags & PROXY_RES_CLIENT_CHUNK)
|
||||||
{
|
{
|
||||||
proxy->expect_100 |= AWAIT_CON;
|
proxy->resflags |= PROXY_RES_AWAIT_RESCON;
|
||||||
task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -3509,7 +3511,7 @@ qse_printf (QSE_T("TRAILING DATA=[%hs]\n"), &QSE_MBS_CHAR(proxy->res,proxy->res_
|
|||||||
task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
task->trigger[2].mask |= QSE_HTTPD_TASK_TRIGGER_WRITE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (proxy->expect_100 & RECEIVED_100)
|
else if (proxy->resflags & PROXY_RES_RECEIVED_100)
|
||||||
{
|
{
|
||||||
/* 100 continue has been received but
|
/* 100 continue has been received but
|
||||||
* the actual response has not. */
|
* the actual response has not. */
|
||||||
|
@ -1080,7 +1080,7 @@ qse_printf (QSE_T("chunked cgi... delaying until contents are received\n"));
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* to support the chunked request,
|
/* to support the chunked request,
|
||||||
* i need to wait until it's compelted and invoke cgi */
|
* i need to wait until it's completed and invoke cgi */
|
||||||
if (req->attr.chunked)
|
if (req->attr.chunked)
|
||||||
{
|
{
|
||||||
qse_printf (QSE_T("Entasking chunked CGI...\n"));
|
qse_printf (QSE_T("Entasking chunked CGI...\n"));
|
||||||
|
Loading…
Reference in New Issue
Block a user