fixed a bug of sending http/1.0 taken from the peer while chunking.
enhanced proxy handling in general
This commit is contained in:
parent
e360d3396c
commit
654003e06d
@ -74,6 +74,8 @@ struct qse_htrd_t
|
|||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
int flags;
|
||||||
|
|
||||||
int crlf; /* crlf status */
|
int crlf; /* crlf status */
|
||||||
qse_size_t plen; /* raw request length excluding crlf */
|
qse_size_t plen; /* raw request length excluding crlf */
|
||||||
qse_size_t need; /* number of octets needed for contents */
|
qse_size_t need; /* number of octets needed for contents */
|
||||||
@ -86,8 +88,7 @@ struct qse_htrd_t
|
|||||||
} chunk;
|
} chunk;
|
||||||
} s; /* state */
|
} s; /* state */
|
||||||
|
|
||||||
|
/* buffers needed for processing a request */
|
||||||
/* buffers needed to for processing a request */
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
qse_htob_t raw; /* buffer to hold raw octets */
|
qse_htob_t raw; /* buffer to hold raw octets */
|
||||||
@ -163,8 +164,13 @@ int qse_htrd_feed (
|
|||||||
qse_size_t len /**< number of octets */
|
qse_size_t len /**< number of octets */
|
||||||
);
|
);
|
||||||
|
|
||||||
int qse_htrd_read (
|
/**
|
||||||
qse_htrd_t* htrd /**< htrd */
|
* The qse_htrd_halt() function indicates the end of feeeding
|
||||||
|
* if the current response should be processed until the
|
||||||
|
* connection is closed.
|
||||||
|
*/
|
||||||
|
int qse_htrd_halt (
|
||||||
|
qse_htrd_t* htrd
|
||||||
);
|
);
|
||||||
|
|
||||||
int qse_htrd_scanqparam (
|
int qse_htrd_scanqparam (
|
||||||
|
@ -81,10 +81,11 @@ struct qse_htre_t
|
|||||||
/* special attributes derived from the header */
|
/* special attributes derived from the header */
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
int chunked;
|
#define QSE_HTRE_ATTR_CHUNKED (1 << 0)
|
||||||
int content_length_set;
|
#define QSE_HTRE_ATTR_LENGTH (1 << 1)
|
||||||
|
#define QSE_HTRE_ATTR_KEEPALIVE (1 << 2)
|
||||||
|
int flags;
|
||||||
qse_size_t content_length;
|
qse_size_t content_length;
|
||||||
int keepalive;
|
|
||||||
const qse_mchar_t* expect;
|
const qse_mchar_t* expect;
|
||||||
const qse_mchar_t* status;
|
const qse_mchar_t* status;
|
||||||
} attr;
|
} attr;
|
||||||
|
@ -26,6 +26,8 @@ QSE_IMPLEMENT_COMMON_FUNCTIONS (htrd)
|
|||||||
|
|
||||||
static const qse_mchar_t NUL = QSE_MT('\0');
|
static const qse_mchar_t NUL = QSE_MT('\0');
|
||||||
|
|
||||||
|
#define CONSUME_UNTIL_CLOSE (1 << 0)
|
||||||
|
|
||||||
static QSE_INLINE int is_whspace_octet (qse_mchar_t c)
|
static QSE_INLINE int is_whspace_octet (qse_mchar_t c)
|
||||||
{
|
{
|
||||||
return c == QSE_MT(' ') || c == QSE_MT('\t') || c == QSE_MT('\r') || c == QSE_MT('\n');
|
return c == QSE_MT(' ') || c == QSE_MT('\t') || c == QSE_MT('\r') || c == QSE_MT('\n');
|
||||||
@ -425,7 +427,7 @@ static qse_mchar_t* parse_initial_line (
|
|||||||
if (htrd->re.version.major > 1 ||
|
if (htrd->re.version.major > 1 ||
|
||||||
(htrd->re.version.major == 1 && htrd->re.version.minor >= 1))
|
(htrd->re.version.major == 1 && htrd->re.version.minor >= 1))
|
||||||
{
|
{
|
||||||
htrd->re.attr.keepalive = 1;
|
htrd->re.attr.flags |= QSE_HTRE_ATTR_KEEPALIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ++p;
|
return ++p;
|
||||||
@ -469,7 +471,7 @@ static int capture_connection (qse_htrd_t* htrd, qse_htb_pair_t* pair)
|
|||||||
"close", 5);
|
"close", 5);
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
{
|
{
|
||||||
htrd->re.attr.keepalive = 0;
|
htrd->re.attr.flags &= ~QSE_HTRE_ATTR_KEEPALIVE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -478,7 +480,7 @@ static int capture_connection (qse_htrd_t* htrd, qse_htb_pair_t* pair)
|
|||||||
"keep-alive", 10);
|
"keep-alive", 10);
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
{
|
{
|
||||||
htrd->re.attr.keepalive = 1;
|
htrd->re.attr.flags |= QSE_HTRE_ATTR_KEEPALIVE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -494,7 +496,7 @@ static int capture_connection (qse_htrd_t* htrd, qse_htb_pair_t* pair)
|
|||||||
if (htrd->re.version.major < 1 ||
|
if (htrd->re.version.major < 1 ||
|
||||||
(htrd->re.version.major == 1 && htrd->re.version.minor <= 0))
|
(htrd->re.version.major == 1 && htrd->re.version.minor <= 0))
|
||||||
{
|
{
|
||||||
htrd->re.attr.keepalive = 0;
|
htrd->re.attr.flags &= ~QSE_HTRE_ATTR_KEEPALIVE;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -533,7 +535,7 @@ static int capture_content_length (qse_htrd_t* htrd, qse_htb_pair_t* pair)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (htrd->re.attr.chunked && len > 0)
|
if ((htrd->re.attr.flags & QSE_HTRE_ATTR_CHUNKED) && len > 0)
|
||||||
{
|
{
|
||||||
/* content-length is greater than 0
|
/* content-length is greater than 0
|
||||||
* while transfer-encoding: chunked is specified. */
|
* while transfer-encoding: chunked is specified. */
|
||||||
@ -541,8 +543,8 @@ static int capture_content_length (qse_htrd_t* htrd, qse_htb_pair_t* pair)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
htrd->re.attr.flags |= QSE_HTRE_ATTR_LENGTH;
|
||||||
htrd->re.attr.content_length = len;
|
htrd->re.attr.content_length = len;
|
||||||
htrd->re.attr.content_length_set = 1;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -567,13 +569,13 @@ static int capture_transfer_encoding (qse_htrd_t* htrd, qse_htb_pair_t* pair)
|
|||||||
if (n == 0)
|
if (n == 0)
|
||||||
{
|
{
|
||||||
/* if (htrd->re.attr.content_length > 0) */
|
/* if (htrd->re.attr.content_length > 0) */
|
||||||
if (htrd->re.attr.content_length_set)
|
if (htrd->re.attr.flags & QSE_HTRE_ATTR_LENGTH)
|
||||||
{
|
{
|
||||||
/* both content-length and 'transfer-encoding: chunked' are specified. */
|
/* both content-length and 'transfer-encoding: chunked' are specified. */
|
||||||
goto badre;
|
goto badre;
|
||||||
}
|
}
|
||||||
|
|
||||||
htrd->re.attr.chunked = 1;
|
htrd->re.attr.flags |= QSE_HTRE_ATTR_CHUNKED;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1111,8 +1113,7 @@ int qse_htrd_feed (qse_htrd_t* htrd, const qse_mchar_t* req, qse_size_t len)
|
|||||||
/* reset the raw request length */
|
/* reset the raw request length */
|
||||||
htrd->fed.s.plen = 0;
|
htrd->fed.s.plen = 0;
|
||||||
|
|
||||||
if (parse_initial_line_and_headers (htrd, req, ptr - req) <= -1)
|
if (parse_initial_line_and_headers (htrd, req, ptr - req) <= -1) return -1;
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* compelete request header is received */
|
/* compelete request header is received */
|
||||||
header_completed_during_this_feed = 1;
|
header_completed_during_this_feed = 1;
|
||||||
@ -1149,10 +1150,10 @@ int qse_htrd_feed (qse_htrd_t* htrd, const qse_mchar_t* req, qse_size_t len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* carry on processing content body fed together with the header */
|
/* carry on processing content body fed together with the header */
|
||||||
if (htrd->re.attr.chunked)
|
if (htrd->re.attr.flags & QSE_HTRE_ATTR_CHUNKED)
|
||||||
{
|
{
|
||||||
/* transfer-encoding: chunked */
|
/* transfer-encoding: chunked */
|
||||||
QSE_ASSERT (!htrd->re.attr.content_length_set);
|
QSE_ASSERT (!(htrd->re.attr.flags & QSE_HTRE_ATTR_LENGTH));
|
||||||
|
|
||||||
dechunk_start:
|
dechunk_start:
|
||||||
htrd->fed.s.chunk.phase = GET_CHUNK_LEN;
|
htrd->fed.s.chunk.phase = GET_CHUNK_LEN;
|
||||||
@ -1195,7 +1196,31 @@ int qse_htrd_feed (qse_htrd_t* htrd, const qse_mchar_t* req, qse_size_t len)
|
|||||||
{
|
{
|
||||||
/* we need to read as many octets as
|
/* we need to read as many octets as
|
||||||
* Content-Length */
|
* Content-Length */
|
||||||
htrd->fed.s.need = htrd->re.attr.content_length;
|
if ((htrd->option & QSE_HTRD_RESPONSE) &&
|
||||||
|
!(htrd->re.attr.flags & QSE_HTRE_ATTR_LENGTH) &&
|
||||||
|
!(htrd->re.attr.flags & QSE_HTRE_ATTR_KEEPALIVE))
|
||||||
|
{
|
||||||
|
/* for a response, no content-length and
|
||||||
|
* no chunk are specified and 'connection'
|
||||||
|
* is to close. i must read until the
|
||||||
|
* connection is closed. however, there isn't
|
||||||
|
* any good way to know when to stop from
|
||||||
|
* within this function. so the caller
|
||||||
|
* can call qse_htrd_halt() for this. */
|
||||||
|
|
||||||
|
/* set this to the maximum in a type safe way
|
||||||
|
* assuming it's unsigned. the problem of
|
||||||
|
* the current implementation is that
|
||||||
|
* it can't receive more than */
|
||||||
|
htrd->fed.s.need = 0;
|
||||||
|
htrd->fed.s.need = ~htrd->fed.s.need;
|
||||||
|
htrd->fed.s.flags |= CONSUME_UNTIL_CLOSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
htrd->fed.s.need = htrd->re.attr.content_length;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (htrd->fed.s.need > 0)
|
if (htrd->fed.s.need > 0)
|
||||||
@ -1209,7 +1234,17 @@ int qse_htrd_feed (qse_htrd_t* htrd, const qse_mchar_t* req, qse_size_t len)
|
|||||||
{
|
{
|
||||||
/* the data is not as large as needed */
|
/* the data is not as large as needed */
|
||||||
if (push_content (htrd, ptr, avail) <= -1) return -1;
|
if (push_content (htrd, ptr, avail) <= -1) return -1;
|
||||||
htrd->fed.s.need -= avail;
|
|
||||||
|
if (!(htrd->fed.s.flags & CONSUME_UNTIL_CLOSE))
|
||||||
|
{
|
||||||
|
/* i don't decrement htrd->fed.s.need
|
||||||
|
* if i should read until connection is closed.
|
||||||
|
* well, unless set your own callback,
|
||||||
|
* push_content() above will fail
|
||||||
|
* if too much has been received already */
|
||||||
|
htrd->fed.s.need -= avail;
|
||||||
|
}
|
||||||
|
|
||||||
/* we didn't get a complete content yet */
|
/* we didn't get a complete content yet */
|
||||||
goto feedme_more;
|
goto feedme_more;
|
||||||
}
|
}
|
||||||
@ -1218,7 +1253,8 @@ int qse_htrd_feed (qse_htrd_t* htrd, const qse_mchar_t* req, qse_size_t len)
|
|||||||
/* we got all or more than needed */
|
/* we got all or more than needed */
|
||||||
if (push_content (htrd, ptr, htrd->fed.s.need) <= -1) return -1;
|
if (push_content (htrd, ptr, htrd->fed.s.need) <= -1) return -1;
|
||||||
ptr += htrd->fed.s.need;
|
ptr += htrd->fed.s.need;
|
||||||
htrd->fed.s.need = 0;
|
if (!(htrd->fed.s.flags & CONSUME_UNTIL_CLOSE))
|
||||||
|
htrd->fed.s.need = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1361,6 +1397,33 @@ feedme_more:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int qse_htrd_halt (qse_htrd_t* htrd)
|
||||||
|
{
|
||||||
|
if (htrd->fed.s.flags & CONSUME_UNTIL_CLOSE)
|
||||||
|
{
|
||||||
|
qse_htre_completecontent (&htrd->re);
|
||||||
|
|
||||||
|
if (htrd->recbs->handle)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
htrd->errnum = QSE_HTRD_ENOERR;
|
||||||
|
n = htrd->recbs->handle (htrd, &htrd->re);
|
||||||
|
if (n <= -1)
|
||||||
|
{
|
||||||
|
if (htrd->errnum == QSE_HTRD_ENOERR)
|
||||||
|
htrd->errnum = QSE_HTRD_ERECBS;
|
||||||
|
/* need to clear request on error?
|
||||||
|
clear_feed (htrd); */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clear_feed (htrd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
int qse_htrd_scanqparam (qse_htrd_t* htrd, const qse_mcstr_t* cstr)
|
int qse_htrd_scanqparam (qse_htrd_t* htrd, const qse_mcstr_t* cstr)
|
||||||
{
|
{
|
||||||
|
@ -36,6 +36,11 @@
|
|||||||
|
|
||||||
#define MAX_SEND_SIZE 4096
|
#define MAX_SEND_SIZE 4096
|
||||||
|
|
||||||
|
/* TODO:
|
||||||
|
* many functions in this file use qse_size_t.
|
||||||
|
* so the size data transfers is limited by this type.
|
||||||
|
* break this barrier... */
|
||||||
|
|
||||||
static qse_http_version_t http_v11 = { 1, 1 };
|
static qse_http_version_t http_v11 = { 1, 1 };
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
@ -400,7 +405,8 @@ qse_httpd_task_t* qse_httpd_entaskerror (
|
|||||||
{
|
{
|
||||||
return entask_error (
|
return entask_error (
|
||||||
httpd, client, pred, code,
|
httpd, client, pred, code,
|
||||||
qse_htre_getversion(req), req->attr.keepalive);
|
qse_htre_getversion(req),
|
||||||
|
(req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
@ -431,7 +437,7 @@ qse_httpd_task_t* qse_httpd_entaskauth (
|
|||||||
httpd, client, pred,
|
httpd, client, pred,
|
||||||
QSE_MT("HTTP/%d.%d 401 Unauthorized\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"),
|
QSE_MT("HTTP/%d.%d 401 Unauthorized\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,
|
version->major, version->minor,
|
||||||
(req->attr.keepalive? QSE_MT("keep-alive"): QSE_MT("close")),
|
((req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE)? QSE_MT("keep-alive"): QSE_MT("close")),
|
||||||
realm, (unsigned long)qse_mbslen(lmsg) + 4, lmsg);
|
realm, (unsigned long)qse_mbslen(lmsg) + 4, lmsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1196,7 +1202,7 @@ qse_httpd_task_t* qse_httpd_entaskfile (
|
|||||||
QSE_MEMSET (&data, 0, QSE_SIZEOF(data));
|
QSE_MEMSET (&data, 0, QSE_SIZEOF(data));
|
||||||
data.path = path;
|
data.path = path;
|
||||||
data.version = *qse_htre_getversion(req);
|
data.version = *qse_htre_getversion(req);
|
||||||
data.keepalive = req->attr.keepalive;
|
data.keepalive = (req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE);
|
||||||
|
|
||||||
tmp = qse_htre_getheaderval(req, QSE_MT("Range"));
|
tmp = qse_htre_getheaderval(req, QSE_MT("Range"));
|
||||||
if (tmp)
|
if (tmp)
|
||||||
@ -1414,7 +1420,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.flags & QSE_HTRE_ATTR_LENGTH)
|
||||||
{
|
{
|
||||||
cgi->resflags |= CGI_RES_SCRIPT_LENGTH;
|
cgi->resflags |= CGI_RES_SCRIPT_LENGTH;
|
||||||
cgi->script_output_length = req->attr.content_length;
|
cgi->script_output_length = req->attr.content_length;
|
||||||
@ -1805,7 +1811,7 @@ static int task_init_cgi (
|
|||||||
qse_mbscpy ((qse_mchar_t*)(cgi + 1), arg->path);
|
qse_mbscpy ((qse_mchar_t*)(cgi + 1), arg->path);
|
||||||
cgi->path = (qse_mchar_t*)(cgi + 1);
|
cgi->path = (qse_mchar_t*)(cgi + 1);
|
||||||
cgi->version = *qse_htre_getversion(arg->req);
|
cgi->version = *qse_htre_getversion(arg->req);
|
||||||
cgi->keepalive = arg->req->attr.keepalive;
|
cgi->keepalive = (arg->req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE);
|
||||||
cgi->nph = arg->nph;
|
cgi->nph = arg->nph;
|
||||||
cgi->req = QSE_NULL;
|
cgi->req = QSE_NULL;
|
||||||
|
|
||||||
@ -1826,7 +1832,7 @@ static int task_init_cgi (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!(arg->req->state & QSE_HTRE_COMPLETED) &&
|
if (!(arg->req->state & QSE_HTRE_COMPLETED) &&
|
||||||
!arg->req->attr.content_length_set)
|
!(arg->req->attr.flags & QSE_HTRE_ATTR_LENGTH))
|
||||||
{
|
{
|
||||||
/* if the request is not completed and doesn't have
|
/* if the request is not completed and doesn't have
|
||||||
* content-length set, it's not really possible to
|
* content-length set, it's not really possible to
|
||||||
@ -1859,8 +1865,9 @@ static int task_init_cgi (
|
|||||||
* should reach here. if content-length is set
|
* should reach here. if content-length is set
|
||||||
* the length should match len. */
|
* the length should match len. */
|
||||||
QSE_ASSERT (len > 0);
|
QSE_ASSERT (len > 0);
|
||||||
QSE_ASSERT (!arg->req->attr.content_length_set ||
|
QSE_ASSERT (!(arg->req->attr.flags & QSE_HTRE_ATTR_LENGTH) ||
|
||||||
(arg->req->attr.content_length_set && arg->req->attr.content_length == len));
|
((arg->req->attr.flags & QSE_HTRE_ATTR_LENGTH) &&
|
||||||
|
arg->req->attr.content_length == len));
|
||||||
cgi->reqflags |= CGI_REQ_GOTALL;
|
cgi->reqflags |= CGI_REQ_GOTALL;
|
||||||
content_length = len;
|
content_length = len;
|
||||||
}
|
}
|
||||||
@ -1885,7 +1892,7 @@ static int task_init_cgi (
|
|||||||
cgi->req = arg->req;
|
cgi->req = arg->req;
|
||||||
qse_htre_setconcb (cgi->req, cgi_snatch_client_input, task);
|
qse_htre_setconcb (cgi->req, cgi_snatch_client_input, task);
|
||||||
|
|
||||||
QSE_ASSERT (arg->req->attr.content_length_set);
|
QSE_ASSERT (arg->req->attr.flags & QSE_HTRE_ATTR_LENGTH);
|
||||||
content_length = arg->req->attr.content_length;
|
content_length = arg->req->attr.content_length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2663,7 +2670,6 @@ static int proxy_snatch_peer_output (
|
|||||||
* the client should be chunked */
|
* 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??? */
|
/* TODO: better condition for compaction??? */
|
||||||
if (proxy->res_pending > 0 && proxy->res_consumed > 0)
|
if (proxy->res_pending > 0 && proxy->res_consumed > 0)
|
||||||
{
|
{
|
||||||
@ -2740,6 +2746,7 @@ static int proxy_htrd_peek_peer_output (qse_htrd_t* htrd, qse_htre_t* res)
|
|||||||
/* 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
|
||||||
* multiple responses in task_main_proxy_2 (). */
|
* multiple responses in task_main_proxy_2 (). */
|
||||||
|
qse_printf (QSE_T("XXXXXXXXXXXXXXXXXXXXXXxx\n"));
|
||||||
proxy->httpd->errnum = QSE_HTTPD_EINVAL;
|
proxy->httpd->errnum = QSE_HTTPD_EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -2772,17 +2779,9 @@ qse_printf (QSE_T("10000000000000000000000000000 CONTINUE 1000000000000000000000
|
|||||||
proxy->resflags |= PROXY_RES_RECEIVED_RESHDR;
|
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 */
|
|
||||||
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_htre_getscodestr(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_htre_getsmesg(res)) == (qse_size_t)-1) return -1;
|
|
||||||
if (qse_mbs_cat (proxy->res, QSE_MT("\r\n")) == (qse_size_t)-1) return -1;
|
|
||||||
/* end initial line */
|
|
||||||
|
|
||||||
keepalive = proxy->keepalive;
|
keepalive = proxy->keepalive;
|
||||||
if (res->attr.content_length_set)
|
if (res->attr.flags & QSE_HTRE_ATTR_LENGTH)
|
||||||
{
|
{
|
||||||
/* the response from the peer is length based */
|
/* the response from the peer is length based */
|
||||||
proxy->resflags |= PROXY_RES_PEER_LENGTH;
|
proxy->resflags |= PROXY_RES_PEER_LENGTH;
|
||||||
@ -2797,13 +2796,7 @@ qse_printf (QSE_T("NORMAL REPLY 222222222222222222222 NORMAL REPLY\n"));
|
|||||||
/* chunk response when writing back to client */
|
/* chunk response when writing back to client */
|
||||||
proxy->resflags |= PROXY_RES_CLIENT_CHUNK;
|
proxy->resflags |= PROXY_RES_CLIENT_CHUNK;
|
||||||
|
|
||||||
if (qse_mbs_cat (proxy->res, QSE_MT("Transfer-Encoding: chunked\r\n")) == (qse_size_t)-1)
|
if (res->attr.flags & QSE_HTRE_ATTR_CHUNKED)
|
||||||
{
|
|
||||||
proxy->httpd->errnum = QSE_HTTPD_ENOMEM;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (res->attr.chunked)
|
|
||||||
{
|
{
|
||||||
/* mark the peer output is chunked */
|
/* mark the peer output is chunked */
|
||||||
proxy->resflags |= PROXY_RES_PEER_CHUNK;
|
proxy->resflags |= PROXY_RES_PEER_CHUNK;
|
||||||
@ -2822,13 +2815,42 @@ qse_printf (QSE_T("NORMAL REPLY 222222222222222222222 NORMAL REPLY\n"));
|
|||||||
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.flags & QSE_HTRE_ATTR_CHUNKED)
|
||||||
proxy->resflags |= PROXY_RES_PEER_CHUNK;
|
proxy->resflags |= PROXY_RES_PEER_CHUNK;
|
||||||
else
|
else
|
||||||
proxy->resflags |= PROXY_RES_PEER_CLOSE;
|
proxy->resflags |= PROXY_RES_PEER_CLOSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* begin initial line */
|
||||||
|
if (proxy->resflags & PROXY_RES_CLIENT_CHUNK &&
|
||||||
|
qse_comparehttpversions (&res->version, &http_v11) < 0)
|
||||||
|
{
|
||||||
|
qse_mchar_t vbuf[64];
|
||||||
|
snprintf (vbuf, QSE_COUNTOF(vbuf), QSE_MT("HTTP/%d.%d"),
|
||||||
|
(int)proxy->version.major, (int)proxy->version.minor);
|
||||||
|
if (qse_mbs_cat (proxy->res, vbuf) == (qse_size_t)-1) return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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_htre_getscodestr(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_htre_getsmesg(res)) == (qse_size_t)-1) return -1;
|
||||||
|
if (qse_mbs_cat (proxy->res, QSE_MT("\r\n")) == (qse_size_t)-1) return -1;
|
||||||
|
/* end initial line */
|
||||||
|
|
||||||
|
if (proxy->resflags & PROXY_RES_CLIENT_CHUNK)
|
||||||
|
{
|
||||||
|
if (qse_mbs_cat (proxy->res, QSE_MT("Transfer-Encoding: chunked\r\n")) == (qse_size_t)-1)
|
||||||
|
{
|
||||||
|
proxy->httpd->errnum = QSE_HTTPD_ENOMEM;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (qse_mbs_cat (proxy->res, (keepalive? QSE_MT("Connection: keep-alive\r\n"): QSE_MT("Connection: close\r\n"))) == (qse_size_t)-1)
|
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;
|
proxy->httpd->errnum = QSE_HTTPD_ENOMEM;
|
||||||
@ -2883,6 +2905,7 @@ qse_printf (QSE_T("PROXY PEER FUCKED - RETURNING TOO MUCH...\n"));
|
|||||||
/* arrange to store further contents received to proxy->res */
|
/* arrange to store further contents received to proxy->res */
|
||||||
qse_htre_setconcb (res, proxy_snatch_peer_output, xtn->task);
|
qse_htre_setconcb (res, proxy_snatch_peer_output, xtn->task);
|
||||||
}
|
}
|
||||||
|
qse_printf (QSE_T("NORMAL REPLY 222222222222222222222 NORMAL REPLY OK\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
proxy->res_pending = QSE_MBS_LEN(proxy->res) - proxy->res_consumed;
|
proxy->res_pending = QSE_MBS_LEN(proxy->res) - proxy->res_consumed;
|
||||||
@ -3000,7 +3023,7 @@ static int task_init_proxy (
|
|||||||
proxy->httpd = httpd;
|
proxy->httpd = httpd;
|
||||||
|
|
||||||
proxy->version = *qse_htre_getversion(arg->req);
|
proxy->version = *qse_htre_getversion(arg->req);
|
||||||
proxy->keepalive = arg->req->attr.keepalive;
|
proxy->keepalive = (arg->req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE);
|
||||||
proxy->peer.nwad = arg->peer_nwad;
|
proxy->peer.nwad = arg->peer_nwad;
|
||||||
proxy->req = QSE_NULL;
|
proxy->req = QSE_NULL;
|
||||||
|
|
||||||
@ -3051,7 +3074,7 @@ len = 1024;
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!(arg->req->state & QSE_HTRE_COMPLETED) &&
|
if (!(arg->req->state & QSE_HTRE_COMPLETED) &&
|
||||||
!arg->req->attr.content_length_set)
|
!(arg->req->attr.flags & QSE_HTRE_ATTR_LENGTH))
|
||||||
{
|
{
|
||||||
/* if the request is not completed and doesn't have
|
/* if the request is not completed and doesn't have
|
||||||
* content-length set, it's not really possible to
|
* content-length set, it's not really possible to
|
||||||
@ -3074,8 +3097,9 @@ len = 1024;
|
|||||||
* should reach here. if content-length is set
|
* should reach here. if content-length is set
|
||||||
* the length should match len. */
|
* the length should match len. */
|
||||||
QSE_ASSERT (len > 0);
|
QSE_ASSERT (len > 0);
|
||||||
QSE_ASSERT (!arg->req->attr.content_length_set ||
|
QSE_ASSERT (!(arg->req->attr.flags & QSE_HTRE_ATTR_LENGTH) ||
|
||||||
(arg->req->attr.content_length_set && arg->req->attr.content_length == len));
|
((arg->req->attr.flags & QSE_HTRE_ATTR_LENGTH) &&
|
||||||
|
arg->req->attr.content_length == len));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -3093,7 +3117,7 @@ len = 1024;
|
|||||||
* htrd calls invokes this callback. */
|
* htrd calls invokes this callback. */
|
||||||
proxy->req = arg->req;
|
proxy->req = arg->req;
|
||||||
qse_htre_setconcb (proxy->req, proxy_snatch_client_input, task);
|
qse_htre_setconcb (proxy->req, proxy_snatch_client_input, task);
|
||||||
QSE_ASSERT (arg->req->attr.content_length_set);
|
QSE_ASSERT (arg->req->attr.flags & QSE_HTRE_ATTR_LENGTH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3449,20 +3473,20 @@ qse_printf (QSE_T("#####PREMATURE EOF FROM PEER\n"));
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qse_printf (QSE_T("#####PREMATURE EOF FROM PEER CLIENT CHUNK\n"));
|
|
||||||
QSE_ASSERT (proxy->resflags & PROXY_RES_CLIENT_CHUNK);
|
QSE_ASSERT (proxy->resflags & PROXY_RES_CLIENT_CHUNK);
|
||||||
|
|
||||||
if (proxy->resflags & PROXY_RES_PEER_CLOSE)
|
if (proxy->resflags & PROXY_RES_PEER_CLOSE)
|
||||||
{
|
{
|
||||||
/* i should compelte the content manually
|
/* i should stop the reader manually since the
|
||||||
* since the end of content is indicated by
|
* end of content is indicated by close in this
|
||||||
* close in this case. */
|
* case. call qse_htrd_halt() for this. */
|
||||||
qse_htre_completecontent (&proxy->peer_htrd->re);
|
qse_htrd_halt (proxy->peer_htrd);
|
||||||
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;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qse_printf (QSE_T("#####PREMATURE EOF FROM PEER CLIENT CHUNK\n"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3550,6 +3574,7 @@ static int task_main_proxy_1 (
|
|||||||
/* improve error conversion */
|
/* improve error conversion */
|
||||||
if (httpd->errnum == QSE_HTTPD_ENOENT) http_errnum = 404;
|
if (httpd->errnum == QSE_HTTPD_ENOENT) http_errnum = 404;
|
||||||
else if (httpd->errnum == QSE_HTTPD_EACCES) http_errnum = 403;
|
else if (httpd->errnum == QSE_HTTPD_EACCES) http_errnum = 403;
|
||||||
|
qse_printf (QSE_T("task_main_proxy_1.... ERROR \n"));
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3589,11 +3614,13 @@ static int task_main_proxy (
|
|||||||
proxy_peer_htrd_xtn_t* xtn;
|
proxy_peer_htrd_xtn_t* xtn;
|
||||||
int http_errnum = 500;
|
int http_errnum = 500;
|
||||||
int n;
|
int n;
|
||||||
|
qse_printf (QSE_T("task_main_proxy....\n"));
|
||||||
|
|
||||||
if (proxy->init_failed) goto oops;
|
if (proxy->init_failed) goto oops;
|
||||||
|
|
||||||
/* set up a http reader to read a response from the peer */
|
/* set up a http reader to read a response from the peer */
|
||||||
proxy->peer_htrd = qse_htrd_open (httpd->mmgr, QSE_SIZEOF(proxy_peer_htrd_xtn_t));
|
proxy->peer_htrd = qse_htrd_open (
|
||||||
|
httpd->mmgr, QSE_SIZEOF(proxy_peer_htrd_xtn_t));
|
||||||
if (proxy->peer_htrd == QSE_NULL) goto oops;
|
if (proxy->peer_htrd == QSE_NULL) goto oops;
|
||||||
xtn = (proxy_peer_htrd_xtn_t*) qse_htrd_getxtn (proxy->peer_htrd);
|
xtn = (proxy_peer_htrd_xtn_t*) qse_htrd_getxtn (proxy->peer_htrd);
|
||||||
xtn->proxy = proxy;
|
xtn->proxy = proxy;
|
||||||
@ -3614,6 +3641,7 @@ static int task_main_proxy (
|
|||||||
/* TODO: translate error code to http error... */
|
/* TODO: translate error code to http error... */
|
||||||
if (httpd->errnum == QSE_HTTPD_ENOENT) http_errnum = 404;
|
if (httpd->errnum == QSE_HTTPD_ENOENT) http_errnum = 404;
|
||||||
else if (httpd->errnum == QSE_HTTPD_EACCES) http_errnum = 403;
|
else if (httpd->errnum == QSE_HTTPD_EACCES) http_errnum = 403;
|
||||||
|
qse_printf (QSE_T("caanot open peer....\n"));
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,8 +302,9 @@ static qse_httpd_client_t* new_client (
|
|||||||
client->status = tmpl->status;
|
client->status = tmpl->status;
|
||||||
client->handle = tmpl->handle;
|
client->handle = tmpl->handle;
|
||||||
client->handle2 = tmpl->handle2;
|
client->handle2 = tmpl->handle2;
|
||||||
client->local_addr = tmpl->local_addr;
|
|
||||||
client->remote_addr = tmpl->remote_addr;
|
client->remote_addr = tmpl->remote_addr;
|
||||||
|
client->local_addr = tmpl->local_addr;
|
||||||
|
client->orgdst_addr = tmpl->orgdst_addr;
|
||||||
|
|
||||||
xtn = (htrd_xtn_t*)qse_htrd_getxtn (client->htrd);
|
xtn = (htrd_xtn_t*)qse_htrd_getxtn (client->htrd);
|
||||||
xtn->httpd = httpd;
|
xtn->httpd = httpd;
|
||||||
@ -458,10 +459,11 @@ qse_printf (QSE_T("MUX ADDHND CLIENT READ %d\n"), client->handle.i);
|
|||||||
|
|
||||||
{
|
{
|
||||||
/* TODO: proper logging */
|
/* TODO: proper logging */
|
||||||
qse_char_t tmp[128], tmp2[128];
|
qse_char_t tmp[128], tmp2[128], tmp3[128];
|
||||||
qse_nwadtostr (&client->local_addr, tmp, QSE_COUNTOF(tmp), QSE_NWADTOSTR_ALL);
|
qse_nwadtostr (&client->local_addr, tmp, QSE_COUNTOF(tmp), QSE_NWADTOSTR_ALL);
|
||||||
qse_nwadtostr (&client->remote_addr, tmp2, QSE_COUNTOF(tmp2), QSE_NWADTOSTR_ALL);
|
qse_nwadtostr (&client->orgdst_addr, tmp2, QSE_COUNTOF(tmp2), QSE_NWADTOSTR_ALL);
|
||||||
qse_printf (QSE_T("connection %d accepted %s from %s\n"), client->handle.i, tmp, tmp2);
|
qse_nwadtostr (&client->remote_addr, tmp3, QSE_COUNTOF(tmp3), QSE_NWADTOSTR_ALL);
|
||||||
|
qse_printf (QSE_T("connection %d accepted %s(%s from %s\n"), client->handle.i, tmp, tmp2, tmp3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -141,6 +141,7 @@ static qse_httpd_errnum_t syserr_to_errnum (int e)
|
|||||||
return QSE_HTTPD_EINVAL;
|
return QSE_HTTPD_EINVAL;
|
||||||
|
|
||||||
case EACCES:
|
case EACCES:
|
||||||
|
case ECONNREFUSED:
|
||||||
return QSE_HTTPD_EACCES;
|
return QSE_HTTPD_EACCES;
|
||||||
|
|
||||||
case ENOENT:
|
case ENOENT:
|
||||||
@ -414,12 +415,6 @@ qse_fprintf (QSE_STDERR, QSE_T("Error: too many client?\n"));
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{
|
|
||||||
qse_char_t buf[100];
|
|
||||||
qse_nwadtostr (&client->orgdst_addr, buf, QSE_COUNTOF(buf), QSE_NWADTOSTR_ALL);
|
|
||||||
qse_printf (QSE_T("ORGDST address : (%s)\n"), buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
client->handle.i = fd;
|
client->handle.i = fd;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -487,7 +482,11 @@ static int peer_connected (qse_httpd_t* httpd, qse_httpd_peer_t* peer)
|
|||||||
if (getsockopt (peer->handle.i, SOL_SOCKET, SO_ERROR, &ret, &len) <= -1) return -1;
|
if (getsockopt (peer->handle.i, SOL_SOCKET, SO_ERROR, &ret, &len) <= -1) return -1;
|
||||||
|
|
||||||
if (ret == EINPROGRESS) return 0;
|
if (ret == EINPROGRESS) return 0;
|
||||||
if (ret != 0) return -1;
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
qse_httpd_seterrnum (httpd, syserr_to_errnum (ret));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return 1; /* connection completed */
|
return 1; /* connection completed */
|
||||||
}
|
}
|
||||||
@ -533,8 +532,8 @@ struct mux_t
|
|||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
struct mux_ev_t* ptr;
|
struct mux_ev_t** ptr;
|
||||||
qse_size_t capa;
|
qse_size_t capa;
|
||||||
} mev;
|
} mev;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -564,7 +563,13 @@ static void mux_close (qse_httpd_t* httpd, void* vmux)
|
|||||||
{
|
{
|
||||||
struct mux_t* mux = (struct mux_t*)vmux;
|
struct mux_t* mux = (struct mux_t*)vmux;
|
||||||
if (mux->ee.ptr) qse_httpd_freemem (httpd, mux->ee.ptr);
|
if (mux->ee.ptr) qse_httpd_freemem (httpd, mux->ee.ptr);
|
||||||
if (mux->mev.ptr) qse_httpd_freemem (httpd, mux->mev.ptr);
|
if (mux->mev.ptr)
|
||||||
|
{
|
||||||
|
qse_size_t i;
|
||||||
|
for (i = 0; i < mux->mev.capa; i++)
|
||||||
|
if (mux->mev.ptr[i]) qse_httpd_freemem (httpd, mux->mev.ptr[i]);
|
||||||
|
qse_httpd_freemem (httpd, mux->mev.ptr);
|
||||||
|
}
|
||||||
close (mux->fd);
|
close (mux->fd);
|
||||||
qse_httpd_freemem (httpd, mux);
|
qse_httpd_freemem (httpd, mux);
|
||||||
}
|
}
|
||||||
@ -589,20 +594,33 @@ static int mux_addhnd (
|
|||||||
|
|
||||||
if (handle.i >= mux->mev.capa)
|
if (handle.i >= mux->mev.capa)
|
||||||
{
|
{
|
||||||
struct mux_ev_t* tmp;
|
struct mux_ev_t** tmp;
|
||||||
qse_size_t tmpcapa;
|
qse_size_t tmpcapa, i;
|
||||||
|
|
||||||
tmpcapa = (((handle.i + MUX_EV_ALIGN) / MUX_EV_ALIGN) * MUX_EV_ALIGN);
|
tmpcapa = (((handle.i + MUX_EV_ALIGN) / MUX_EV_ALIGN) * MUX_EV_ALIGN);
|
||||||
|
|
||||||
tmp = qse_httpd_reallocmem (
|
tmp = (struct mux_ev_t**) qse_httpd_reallocmem (
|
||||||
httpd, mux->mev.ptr,
|
httpd, mux->mev.ptr,
|
||||||
QSE_SIZEOF(*mux->mev.ptr) * tmpcapa);
|
QSE_SIZEOF(*mux->mev.ptr) * tmpcapa);
|
||||||
if (tmp == QSE_NULL) return -1;
|
if (tmp == QSE_NULL) return -1;
|
||||||
|
|
||||||
|
for (i = mux->mev.capa; i < tmpcapa; i++) tmp[i] = QSE_NULL;
|
||||||
mux->mev.ptr = tmp;
|
mux->mev.ptr = tmp;
|
||||||
mux->mev.capa = tmpcapa;
|
mux->mev.capa = tmpcapa;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mux->mev.ptr[handle.i] == QSE_NULL)
|
||||||
|
{
|
||||||
|
/* the location of the data passed to epoll_ctl()
|
||||||
|
* must not change unless i update the info with epoll()
|
||||||
|
* whenever there is reallocation. so i simply
|
||||||
|
* make mux-mev.ptr reallocatable but auctual
|
||||||
|
* data fixed once allocated. */
|
||||||
|
mux->mev.ptr[handle.i] = qse_httpd_allocmem (
|
||||||
|
httpd, QSE_SIZEOF(*mux->mev.ptr[handle.i]));
|
||||||
|
if (mux->mev.ptr[handle.i] == QSE_NULL) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (mux->ee.len >= mux->ee.capa)
|
if (mux->ee.len >= mux->ee.capa)
|
||||||
{
|
{
|
||||||
struct epoll_event* tmp;
|
struct epoll_event* tmp;
|
||||||
@ -616,8 +634,7 @@ static int mux_addhnd (
|
|||||||
mux->ee.capa = (mux->ee.capa + 1) * 2;
|
mux->ee.capa = (mux->ee.capa + 1) * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
mev = &mux->mev.ptr[handle.i];
|
mev = mux->mev.ptr[handle.i];
|
||||||
|
|
||||||
mev->handle = handle;
|
mev->handle = handle;
|
||||||
mev->reqmask = mask;
|
mev->reqmask = mask;
|
||||||
mev->cbfun = cbfun;
|
mev->cbfun = cbfun;
|
||||||
@ -1070,7 +1087,7 @@ if (qse_htre_getcontentlen(req) > 0)
|
|||||||
if (peek)
|
if (peek)
|
||||||
{
|
{
|
||||||
/* cgi */
|
/* cgi */
|
||||||
if (req->attr.chunked)
|
if (req->attr.flags & QSE_HTRE_ATTR_CHUNKED)
|
||||||
{
|
{
|
||||||
qse_printf (QSE_T("chunked cgi... delaying until contents are received\n"));
|
qse_printf (QSE_T("chunked cgi... delaying until contents are received\n"));
|
||||||
#if 0
|
#if 0
|
||||||
@ -1081,10 +1098,9 @@ qse_printf (QSE_T("chunked cgi... delaying until contents are received\n"));
|
|||||||
if (task) qse_httpd_entaskdisconnect (httpd, client, QSE_NULL);
|
if (task) qse_httpd_entaskdisconnect (httpd, client, QSE_NULL);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (method == QSE_HTTP_POST &&
|
else if (method == QSE_HTTP_POST && !(req->attr.flags & QSE_HTRE_ATTR_LENGTH))
|
||||||
!req->attr.content_length_set)
|
|
||||||
{
|
{
|
||||||
req->attr.keepalive = 0;
|
req->attr.flags &= ~QSE_HTRE_ATTR_KEEPALIVE;
|
||||||
task = qse_httpd_entaskerror (
|
task = qse_httpd_entaskerror (
|
||||||
httpd, client, QSE_NULL, 411, req);
|
httpd, client, QSE_NULL, 411, req);
|
||||||
/* 411 can't keep alive */
|
/* 411 can't keep alive */
|
||||||
@ -1101,7 +1117,7 @@ qse_printf (QSE_T("chunked cgi... delaying until contents are received\n"));
|
|||||||
{
|
{
|
||||||
/* to support the chunked request,
|
/* to support the chunked request,
|
||||||
* i need to wait until it's completed and invoke cgi */
|
* i need to wait until it's completed and invoke cgi */
|
||||||
if (req->attr.chunked)
|
if (req->attr.flags & QSE_HTRE_ATTR_CHUNKED)
|
||||||
{
|
{
|
||||||
qse_printf (QSE_T("Entasking chunked CGI...\n"));
|
qse_printf (QSE_T("Entasking chunked CGI...\n"));
|
||||||
task = qse_httpd_entaskcgi (
|
task = qse_httpd_entaskcgi (
|
||||||
@ -1161,7 +1177,7 @@ qse_printf (QSE_T("Entasking chunked CGI...\n"));
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!req->attr.keepalive)
|
if (!(req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE))
|
||||||
{
|
{
|
||||||
if (!peek)
|
if (!peek)
|
||||||
{
|
{
|
||||||
@ -1236,6 +1252,7 @@ qse_printf (QSE_T("Host not included....\n"));
|
|||||||
{
|
{
|
||||||
qse_nwad_t nwad;
|
qse_nwad_t nwad;
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (qse_nwadequal (&client->local_addr, &client->orgdst_addr))
|
if (qse_nwadequal (&client->local_addr, &client->orgdst_addr))
|
||||||
{
|
{
|
||||||
//qse_strtonwad (QSE_T("192.168.1.55:9000"), &nwad);
|
//qse_strtonwad (QSE_T("192.168.1.55:9000"), &nwad);
|
||||||
@ -1243,13 +1260,16 @@ qse_printf (QSE_T("Host not included....\n"));
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#endif
|
||||||
nwad = client->orgdst_addr;
|
nwad = client->orgdst_addr;
|
||||||
|
#if 0
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
task = qse_httpd_entaskproxy (httpd, client, QSE_NULL, &nwad, req);
|
task = qse_httpd_entaskproxy (httpd, client, QSE_NULL, &nwad, req);
|
||||||
if (task == QSE_NULL) goto oops;
|
if (task == QSE_NULL) goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!req->attr.keepalive)
|
if (!(req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE))
|
||||||
{
|
{
|
||||||
if (!peek)
|
if (!peek)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user