fixed the problem of no percent-encoding of decoded query path in proxying
This commit is contained in:
parent
94f015ea98
commit
f84b27c1de
@ -92,16 +92,19 @@ struct qse_htre_t
|
||||
} s;
|
||||
} u;
|
||||
|
||||
/* special attributes derived from the header */
|
||||
struct
|
||||
{
|
||||
|
||||
#define QSE_HTRE_ATTR_CHUNKED (1 << 0)
|
||||
#define QSE_HTRE_ATTR_LENGTH (1 << 1)
|
||||
#define QSE_HTRE_ATTR_KEEPALIVE (1 << 2)
|
||||
#define QSE_HTRE_ATTR_EXPECT (1 << 3)
|
||||
#define QSE_HTRE_ATTR_EXPECT100 (1 << 4)
|
||||
#define QSE_HTRE_ATTR_PROXIED (1 << 5)
|
||||
#define QSE_HTRE_QPATH_PERDEC (1 << 6) /* the qpath has been percent-decoded */
|
||||
int flags;
|
||||
|
||||
/* special attributes derived from the header */
|
||||
struct
|
||||
{
|
||||
qse_size_t content_length;
|
||||
const qse_mchar_t* status; /* for cgi */
|
||||
} attr;
|
||||
@ -231,6 +234,10 @@ QSE_EXPORT void qse_htre_setconcb (
|
||||
void* ctx
|
||||
);
|
||||
|
||||
QSE_EXPORT int qse_htre_perdecqpath (
|
||||
qse_htre_t* req
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -154,6 +154,13 @@ struct qse_http_range_t
|
||||
};
|
||||
typedef struct qse_http_range_t qse_http_range_t;
|
||||
|
||||
|
||||
enum qse_perenchttpstr_opt_t
|
||||
{
|
||||
QSE_PERENCHTTPSTR_KEEP_SLASH = (1 << 0)
|
||||
};
|
||||
typedef enum qse_perenchttpstr_opt_t qse_perenchttpstr_opt_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -195,20 +202,26 @@ QSE_EXPORT qse_mchar_t* qse_fmthttptime (
|
||||
qse_size_t bufsz
|
||||
);
|
||||
|
||||
/* percent-decode a string */
|
||||
/* percent-decode a string.
|
||||
* returns the number of affected characters.
|
||||
* for example, 0 means that no characters in the input required decoding. */
|
||||
QSE_EXPORT qse_size_t qse_perdechttpstr (
|
||||
const qse_mchar_t* str,
|
||||
qse_mchar_t* buf
|
||||
);
|
||||
|
||||
|
||||
/* percent-encode a string */
|
||||
/* percent-encode a string.
|
||||
* returns the number of affected characters.
|
||||
* for example, 0 means that no characters in the input required encoding. */
|
||||
QSE_EXPORT qse_size_t qse_perenchttpstr (
|
||||
int opt, /**< 0 or bitwise-OR'ed of #qse_perenchttpstr_opt_t */
|
||||
const qse_mchar_t* str,
|
||||
qse_mchar_t* buf
|
||||
);
|
||||
|
||||
QSE_EXPORT qse_mchar_t* qse_perenchttpstrdup (
|
||||
int opt, /**< 0 or bitwise-OR'ed of #qse_perenchttpstr_opt_t */
|
||||
const qse_mchar_t* str,
|
||||
qse_mmgr_t* mmgr
|
||||
);
|
||||
|
@ -444,7 +444,7 @@ static qse_mchar_t* parse_initial_line (qse_htrd_t* htrd, qse_mchar_t* line)
|
||||
if (htrd->re.version.major > 1 ||
|
||||
(htrd->re.version.major == 1 && htrd->re.version.minor >= 1))
|
||||
{
|
||||
htrd->re.attr.flags |= QSE_HTRE_ATTR_KEEPALIVE;
|
||||
htrd->re.flags |= QSE_HTRE_ATTR_KEEPALIVE;
|
||||
}
|
||||
|
||||
return ++p;
|
||||
@ -500,14 +500,14 @@ static int capture_connection (qse_htrd_t* htrd, qse_htb_pair_t* pair)
|
||||
n = qse_mbscmp (val->ptr, QSE_MT("close"));
|
||||
if (n == 0)
|
||||
{
|
||||
htrd->re.attr.flags &= ~QSE_HTRE_ATTR_KEEPALIVE;
|
||||
htrd->re.flags &= ~QSE_HTRE_ATTR_KEEPALIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = qse_mbscmp (val->ptr, QSE_MT("keep-alive"));
|
||||
if (n == 0)
|
||||
{
|
||||
htrd->re.attr.flags |= QSE_HTRE_ATTR_KEEPALIVE;
|
||||
htrd->re.flags |= QSE_HTRE_ATTR_KEEPALIVE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -523,7 +523,7 @@ static int capture_connection (qse_htrd_t* htrd, qse_htb_pair_t* pair)
|
||||
if (htrd->re.version.major < 1 ||
|
||||
(htrd->re.version.major == 1 && htrd->re.version.minor <= 0))
|
||||
{
|
||||
htrd->re.attr.flags &= ~QSE_HTRE_ATTR_KEEPALIVE;
|
||||
htrd->re.flags &= ~QSE_HTRE_ATTR_KEEPALIVE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -568,7 +568,7 @@ static int capture_content_length (qse_htrd_t* htrd, qse_htb_pair_t* pair)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((htrd->re.attr.flags & QSE_HTRE_ATTR_CHUNKED) && len > 0)
|
||||
if ((htrd->re.flags & QSE_HTRE_ATTR_CHUNKED) && len > 0)
|
||||
{
|
||||
/* content-length is greater than 0
|
||||
* while transfer-encoding: chunked is specified. */
|
||||
@ -576,7 +576,7 @@ static int capture_content_length (qse_htrd_t* htrd, qse_htb_pair_t* pair)
|
||||
return -1;
|
||||
}
|
||||
|
||||
htrd->re.attr.flags |= QSE_HTRE_ATTR_LENGTH;
|
||||
htrd->re.flags |= QSE_HTRE_ATTR_LENGTH;
|
||||
htrd->re.attr.content_length = len;
|
||||
return 0;
|
||||
}
|
||||
@ -586,14 +586,14 @@ static int capture_expect (qse_htrd_t* htrd, qse_htb_pair_t* pair)
|
||||
qse_htre_hdrval_t* val;
|
||||
|
||||
/* Expect is included */
|
||||
htrd->re.attr.flags |= QSE_HTRE_ATTR_EXPECT;
|
||||
htrd->re.flags |= QSE_HTRE_ATTR_EXPECT;
|
||||
|
||||
val = QSE_HTB_VPTR(pair);
|
||||
while (val)
|
||||
{
|
||||
/* Expect: 100-continue is included */
|
||||
if (qse_mbscasecmp (val->ptr, QSE_MT("100-continue")) == 0)
|
||||
htrd->re.attr.flags |= QSE_HTRE_ATTR_EXPECT100;
|
||||
htrd->re.flags |= QSE_HTRE_ATTR_EXPECT100;
|
||||
val = val->next;
|
||||
}
|
||||
|
||||
@ -623,13 +623,13 @@ static int capture_transfer_encoding (qse_htrd_t* htrd, qse_htb_pair_t* pair)
|
||||
if (n == 0)
|
||||
{
|
||||
/* if (htrd->re.attr.content_length > 0) */
|
||||
if (htrd->re.attr.flags & QSE_HTRE_ATTR_LENGTH)
|
||||
if (htrd->re.flags & QSE_HTRE_ATTR_LENGTH)
|
||||
{
|
||||
/* both content-length and 'transfer-encoding: chunked' are specified. */
|
||||
goto badre;
|
||||
}
|
||||
|
||||
htrd->re.attr.flags |= QSE_HTRE_ATTR_CHUNKED;
|
||||
htrd->re.flags |= QSE_HTRE_ATTR_CHUNKED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1232,10 +1232,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 */
|
||||
if (htrd->re.attr.flags & QSE_HTRE_ATTR_CHUNKED)
|
||||
if (htrd->re.flags & QSE_HTRE_ATTR_CHUNKED)
|
||||
{
|
||||
/* transfer-encoding: chunked */
|
||||
QSE_ASSERT (!(htrd->re.attr.flags & QSE_HTRE_ATTR_LENGTH));
|
||||
QSE_ASSERT (!(htrd->re.flags & QSE_HTRE_ATTR_LENGTH));
|
||||
|
||||
dechunk_start:
|
||||
htrd->fed.s.chunk.phase = GET_CHUNK_LEN;
|
||||
@ -1279,8 +1279,8 @@ 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
|
||||
* Content-Length */
|
||||
if ((htrd->option & QSE_HTRD_RESPONSE) &&
|
||||
!(htrd->re.attr.flags & QSE_HTRE_ATTR_LENGTH) &&
|
||||
!(htrd->re.attr.flags & QSE_HTRE_ATTR_KEEPALIVE))
|
||||
!(htrd->re.flags & QSE_HTRE_ATTR_LENGTH) &&
|
||||
!(htrd->re.flags & QSE_HTRE_ATTR_KEEPALIVE))
|
||||
{
|
||||
/* for a response, no content-length and
|
||||
* no chunk are specified and 'connection'
|
||||
|
@ -264,3 +264,11 @@ void qse_htre_setconcb (qse_htre_t* re, qse_htre_concb_t concb, void* ctx)
|
||||
re->concb_ctx = ctx;
|
||||
}
|
||||
|
||||
int qse_htre_perdecqpath (qse_htre_t* re)
|
||||
{
|
||||
/* percent decode the query path */
|
||||
if (re->type != QSE_HTRE_Q || (re->flags & QSE_HTRE_QPATH_PERDEC)) return -1;
|
||||
if (qse_perdechttpstr ((re)->u.q.path, (re)->u.q.path) > 0)
|
||||
re->flags |= QSE_HTRE_QPATH_PERDEC;
|
||||
return 0;
|
||||
}
|
||||
|
@ -390,6 +390,7 @@ qse_size_t qse_perdechttpstr (const qse_mchar_t* str, qse_mchar_t* buf)
|
||||
{
|
||||
const qse_mchar_t* p = str;
|
||||
qse_mchar_t* out = buf;
|
||||
qse_size_t dec_count = 0;
|
||||
|
||||
while (*p != QSE_T('\0'))
|
||||
{
|
||||
@ -405,31 +406,51 @@ qse_size_t qse_perdechttpstr (const qse_mchar_t* str, qse_mchar_t* buf)
|
||||
* contains a null character */
|
||||
*out++ = ((q << 4) + w);
|
||||
p += 3;
|
||||
dec_count++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*out++ = *p++;
|
||||
}
|
||||
|
||||
*out = QSE_MT('\0');
|
||||
return out - buf;
|
||||
/*return out - buf;*/
|
||||
return dec_count;
|
||||
}
|
||||
|
||||
#define IS_UNRESERVED(c) \
|
||||
(((c) >= QSE_MT('A') && (c) <= QSE_MT('Z')) || \
|
||||
((c) >= QSE_MT('a') && (c) <= QSE_MT('z')) || \
|
||||
((c) >= QSE_MT('0') && (c) <= QSE_MT('9')) || \
|
||||
(c) == QSE_MT('-') || (c) == QSE_T('_') || \
|
||||
(c) == QSE_MT('.') || (c) == QSE_T('~'))
|
||||
|
||||
#define TO_HEX(v) (QSE_MT("0123456789ABCDEF")[(v) & 15])
|
||||
|
||||
qse_size_t qse_perenchttpstr (const qse_mchar_t* str, qse_mchar_t* buf)
|
||||
qse_size_t qse_perenchttpstr (int opt, const qse_mchar_t* str, qse_mchar_t* buf)
|
||||
{
|
||||
const qse_mchar_t* p = str;
|
||||
qse_mchar_t* out = buf;
|
||||
qse_size_t enc_count = 0;
|
||||
|
||||
if (opt & QSE_PERENCHTTPSTR_KEEP_SLASH)
|
||||
{
|
||||
while (*p != QSE_T('\0'))
|
||||
{
|
||||
if (IS_UNRESERVED(*p) || *p == QSE_MT('/')) *out++ = *p;
|
||||
else
|
||||
{
|
||||
*out++ = QSE_MT('%');
|
||||
*out++ = TO_HEX (*p >> 4);
|
||||
*out++ = TO_HEX (*p & 15);
|
||||
enc_count++;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (*p != QSE_T('\0'))
|
||||
{
|
||||
if (IS_UNRESERVED(*p)) *out++ = *p;
|
||||
@ -438,25 +459,37 @@ qse_size_t qse_perenchttpstr (const qse_mchar_t* str, qse_mchar_t* buf)
|
||||
*out++ = QSE_MT('%');
|
||||
*out++ = TO_HEX (*p >> 4);
|
||||
*out++ = TO_HEX (*p & 15);
|
||||
enc_count++;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
}
|
||||
*out = QSE_MT('\0');
|
||||
return out - buf;
|
||||
/*return out - buf;*/
|
||||
return enc_count;
|
||||
}
|
||||
|
||||
qse_mchar_t* qse_perenchttpstrdup (const qse_mchar_t* str, qse_mmgr_t* mmgr)
|
||||
qse_mchar_t* qse_perenchttpstrdup (int opt, const qse_mchar_t* str, qse_mmgr_t* mmgr)
|
||||
{
|
||||
qse_mchar_t* buf;
|
||||
qse_size_t len = 0;
|
||||
qse_size_t count = 0;
|
||||
|
||||
/* count the number of characters that should be encoded */
|
||||
if (opt & QSE_PERENCHTTPSTR_KEEP_SLASH)
|
||||
{
|
||||
for (len = 0; str[len] != QSE_T('\0'); len++)
|
||||
{
|
||||
if (!IS_UNRESERVED(str[len]) && str[len] != QSE_MT('/')) count++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (len = 0; str[len] != QSE_T('\0'); len++)
|
||||
{
|
||||
if (!IS_UNRESERVED(str[len])) count++;
|
||||
}
|
||||
}
|
||||
|
||||
/* if there are no characters to escape, just return the original string */
|
||||
if (count <= 0) return (qse_mchar_t*)str;
|
||||
@ -466,7 +499,7 @@ qse_mchar_t* qse_perenchttpstrdup (const qse_mchar_t* str, qse_mmgr_t* mmgr)
|
||||
if (buf == QSE_NULL) return QSE_NULL;
|
||||
|
||||
/* perform actual escaping */
|
||||
qse_perenchttpstr (str, buf);
|
||||
qse_perenchttpstr (opt, str, buf);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
@ -304,7 +304,7 @@ static int cgi_htrd_peek_script_output (qse_htrd_t* htrd, qse_htre_t* req)
|
||||
}
|
||||
|
||||
keepalive = cgi->keepalive;
|
||||
if (req->attr.flags & QSE_HTRE_ATTR_LENGTH)
|
||||
if (req->flags & QSE_HTRE_ATTR_LENGTH)
|
||||
{
|
||||
cgi->resflags |= CGI_RES_SCRIPT_LENGTH;
|
||||
cgi->script_output_length = req->attr.content_length;
|
||||
@ -730,7 +730,7 @@ static int task_init_cgi (
|
||||
|
||||
cgi->method = qse_htre_getqmethodtype(arg->req);
|
||||
cgi->version = *qse_htre_getversion(arg->req);
|
||||
cgi->keepalive = (arg->req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE);
|
||||
cgi->keepalive = (arg->req->flags & QSE_HTRE_ATTR_KEEPALIVE);
|
||||
cgi->nph = arg->nph;
|
||||
cgi->req = QSE_NULL;
|
||||
|
||||
@ -747,7 +747,7 @@ static int task_init_cgi (
|
||||
}
|
||||
|
||||
if (!(arg->req->state & QSE_HTRE_COMPLETED) &&
|
||||
!(arg->req->attr.flags & QSE_HTRE_ATTR_LENGTH))
|
||||
!(arg->req->flags & QSE_HTRE_ATTR_LENGTH))
|
||||
{
|
||||
/* if the request is not completed and doesn't have
|
||||
* content-length set, it's not really possible to
|
||||
@ -821,8 +821,8 @@ static int task_init_cgi (
|
||||
* should reach here. if content-length is set
|
||||
* the length should match len. */
|
||||
QSE_ASSERT (len > 0);
|
||||
QSE_ASSERT (!(arg->req->attr.flags & QSE_HTRE_ATTR_LENGTH) ||
|
||||
((arg->req->attr.flags & QSE_HTRE_ATTR_LENGTH) &&
|
||||
QSE_ASSERT (!(arg->req->flags & QSE_HTRE_ATTR_LENGTH) ||
|
||||
((arg->req->flags & QSE_HTRE_ATTR_LENGTH) &&
|
||||
arg->req->attr.content_length == len));
|
||||
cgi->reqflags |= CGI_REQ_GOTALL;
|
||||
content_length = len;
|
||||
@ -848,7 +848,7 @@ static int task_init_cgi (
|
||||
cgi->req = arg->req;
|
||||
qse_htre_setconcb (cgi->req, cgi_snatch_client_input, task);
|
||||
|
||||
QSE_ASSERT (arg->req->attr.flags & QSE_HTRE_ATTR_LENGTH);
|
||||
QSE_ASSERT (arg->req->flags & QSE_HTRE_ATTR_LENGTH);
|
||||
content_length = arg->req->attr.content_length;
|
||||
}
|
||||
}
|
||||
|
@ -155,7 +155,7 @@ static qse_size_t format_dirent (
|
||||
* a lot of file names to escape. */
|
||||
|
||||
/* perform percent-encoding for the anchor */
|
||||
encname = qse_perenchttpstrdup (dirent->name, httpd->mmgr);
|
||||
encname = qse_perenchttpstrdup (0, dirent->name, httpd->mmgr);
|
||||
if (encname == QSE_NULL)
|
||||
{
|
||||
httpd->errnum = QSE_HTTPD_ENOMEM;
|
||||
@ -602,7 +602,7 @@ qse_httpd_task_t* qse_httpd_entaskdir (
|
||||
data.foot.ptr = dir->foot? dir->foot: qse_httpd_getname(httpd);
|
||||
data.foot.len = qse_mbslen(data.foot.ptr);
|
||||
data.version = *qse_htre_getversion(req);
|
||||
data.keepalive = (req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE);
|
||||
data.keepalive = (req->flags & QSE_HTRE_ATTR_KEEPALIVE);
|
||||
data.method = method;
|
||||
|
||||
QSE_MEMSET (&task, 0, QSE_SIZEOF(task));
|
||||
|
@ -541,7 +541,7 @@ qse_httpd_task_t* qse_httpd_entaskfile (
|
||||
data.path.ptr = (qse_mchar_t*)path;
|
||||
data.path.len = qse_mbslen(path);
|
||||
data.version = *qse_htre_getversion(req);
|
||||
data.keepalive = (req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE);
|
||||
data.keepalive = (req->flags & QSE_HTRE_ATTR_KEEPALIVE);
|
||||
data.method = qse_htre_getqmethodtype(req);
|
||||
|
||||
xtnsize = QSE_SIZEOF(task_file_t) + data.path.len + 1;
|
||||
|
@ -575,7 +575,7 @@ static int proxy_htrd_peek_peer_output (qse_htrd_t* htrd, qse_htre_t* res)
|
||||
proxy->resflags |= PROXY_RES_RECEIVED_RESHDR;
|
||||
|
||||
keepalive = proxy->keepalive;
|
||||
if (res->attr.flags & QSE_HTRE_ATTR_LENGTH)
|
||||
if (res->flags & QSE_HTRE_ATTR_LENGTH)
|
||||
{
|
||||
/* the response from the peer is length based */
|
||||
proxy->resflags |= PROXY_RES_PEER_LENGTH;
|
||||
@ -601,7 +601,7 @@ static int proxy_htrd_peek_peer_output (qse_htrd_t* htrd, qse_htre_t* res)
|
||||
/* chunk response when writing back to client */
|
||||
proxy->resflags |= PROXY_RES_CLIENT_CHUNK;
|
||||
|
||||
if (res->attr.flags & QSE_HTRE_ATTR_CHUNKED)
|
||||
if (res->flags & QSE_HTRE_ATTR_CHUNKED)
|
||||
{
|
||||
/* mark the peer output is chunked */
|
||||
proxy->resflags |= PROXY_RES_PEER_CHUNK;
|
||||
@ -623,7 +623,7 @@ static int proxy_htrd_peek_peer_output (qse_htrd_t* htrd, qse_htre_t* res)
|
||||
/* and push the actual disconnection task */
|
||||
if (qse_httpd_entaskdisconnect (httpd, xtn->client, xtn->task) == QSE_NULL) return -1;
|
||||
|
||||
if (res->attr.flags & QSE_HTRE_ATTR_CHUNKED)
|
||||
if (res->flags & QSE_HTRE_ATTR_CHUNKED)
|
||||
proxy->resflags |= PROXY_RES_PEER_CHUNK;
|
||||
else
|
||||
proxy->resflags |= PROXY_RES_PEER_CLOSE;
|
||||
@ -925,7 +925,7 @@ static int task_init_proxy (
|
||||
|
||||
proxy->method = qse_htre_getqmethodtype(arg->req);
|
||||
proxy->version = *qse_htre_getversion(arg->req);
|
||||
proxy->keepalive = (arg->req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE);
|
||||
proxy->keepalive = (arg->req->flags & QSE_HTRE_ATTR_KEEPALIVE);
|
||||
|
||||
proxy->task = task; /* needed for url rewriting */
|
||||
|
||||
@ -1031,6 +1031,7 @@ printf (">>>>>>>>>>>>>>>>>>>>>>>> [%s] <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", proxy
|
||||
{
|
||||
int snatch_needed = 0;
|
||||
|
||||
|
||||
/* compose a request to send to the peer using the request
|
||||
* received from the client */
|
||||
|
||||
@ -1038,7 +1039,26 @@ printf (">>>>>>>>>>>>>>>>>>>>>>>> [%s] <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n", proxy
|
||||
qse_mbs_cat (proxy->reqfwdbuf, QSE_MT(" ")) == (qse_size_t)-1) goto nomem_oops;
|
||||
|
||||
proxy->qpath_pos_in_reqfwdbuf = QSE_STR_LEN(proxy->reqfwdbuf);
|
||||
if (arg->req->flags & QSE_HTRE_QPATH_PERDEC)
|
||||
{
|
||||
/* the query path has been percent-decoded. so encode it back */
|
||||
qse_mchar_t* qpath, * qpath_enc;
|
||||
qse_size_t x;
|
||||
|
||||
qpath = qse_htre_getqpath(arg->req);
|
||||
qpath_enc = qse_perenchttpstrdup (QSE_PERENCHTTPSTR_KEEP_SLASH, qpath, httpd->mmgr);
|
||||
if (qpath_enc == QSE_NULL) goto nomem_oops;
|
||||
|
||||
x = qse_mbs_cat (proxy->reqfwdbuf, qpath_enc);
|
||||
QSE_MMGR_FREE (httpd->mmgr, qpath_enc);
|
||||
|
||||
if (x == (qse_size_t)-1) goto nomem_oops;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* the query path doesn't require encoding or it's never decoded */
|
||||
if (qse_mbs_cat (proxy->reqfwdbuf, qse_htre_getqpath(arg->req)) == (qse_size_t)-1) goto nomem_oops;
|
||||
}
|
||||
|
||||
if (qse_htre_getqparam(arg->req))
|
||||
{
|
||||
@ -1081,7 +1101,7 @@ qse_mbs_ncat (proxy->reqfwdbuf, spc, QSE_COUNTOF(spc));
|
||||
}
|
||||
|
||||
proxy->resflags |= PROXY_RES_AWAIT_RESHDR;
|
||||
if ((arg->req->attr.flags & QSE_HTRE_ATTR_EXPECT100) &&
|
||||
if ((arg->req->flags & QSE_HTRE_ATTR_EXPECT100) &&
|
||||
(arg->req->version.major > 1 || (arg->req->version.major == 1 && arg->req->version.minor >= 1)))
|
||||
{
|
||||
proxy->resflags |= PROXY_RES_AWAIT_100;
|
||||
@ -1115,8 +1135,8 @@ qse_mbs_ncat (proxy->reqfwdbuf, spc, QSE_COUNTOF(spc));
|
||||
if (arg->req->state & QSE_HTRE_DISCARDED)
|
||||
{
|
||||
/* no content to add */
|
||||
if ((arg->req->attr.flags & QSE_HTRE_ATTR_LENGTH) ||
|
||||
(arg->req->attr.flags & QSE_HTRE_ATTR_CHUNKED))
|
||||
if ((arg->req->flags & QSE_HTRE_ATTR_LENGTH) ||
|
||||
(arg->req->flags & QSE_HTRE_ATTR_CHUNKED))
|
||||
{
|
||||
/* i don't add chunk traiers if the
|
||||
* request content has been discarded */
|
||||
@ -1129,15 +1149,15 @@ qse_mbs_ncat (proxy->reqfwdbuf, spc, QSE_COUNTOF(spc));
|
||||
}
|
||||
else if (arg->req->state & QSE_HTRE_COMPLETED)
|
||||
{
|
||||
if (arg->req->attr.flags & QSE_HTRE_ATTR_CHUNKED)
|
||||
if (arg->req->flags & QSE_HTRE_ATTR_CHUNKED)
|
||||
{
|
||||
/* add trailers if any */
|
||||
if (qse_htre_walktrailers (arg->req, proxy_capture_client_trailer, proxy) <= -1) goto nomem_oops;
|
||||
}
|
||||
|
||||
len = qse_htre_getcontentlen(arg->req);
|
||||
if (len > 0 || (arg->req->attr.flags & QSE_HTRE_ATTR_LENGTH) ||
|
||||
(arg->req->attr.flags & QSE_HTRE_ATTR_CHUNKED))
|
||||
if (len > 0 || (arg->req->flags & QSE_HTRE_ATTR_LENGTH) ||
|
||||
(arg->req->flags & QSE_HTRE_ATTR_CHUNKED))
|
||||
{
|
||||
qse_mchar_t buf[64];
|
||||
|
||||
@ -1163,7 +1183,7 @@ qse_mbs_ncat (proxy->reqfwdbuf, spc, QSE_COUNTOF(spc));
|
||||
if (qse_mbs_cat (proxy->reqfwdbuf, QSE_MT("\r\n")) == (qse_size_t)-1) goto nomem_oops;
|
||||
}
|
||||
}
|
||||
else if (arg->req->attr.flags & QSE_HTRE_ATTR_LENGTH)
|
||||
else if (arg->req->flags & QSE_HTRE_ATTR_LENGTH)
|
||||
{
|
||||
/* the Content-Length header field is contained in the request. */
|
||||
qse_mchar_t buf[64];
|
||||
@ -1191,7 +1211,7 @@ qse_mbs_ncat (proxy->reqfwdbuf, spc, QSE_COUNTOF(spc));
|
||||
/* if this request is not chunked nor not length based,
|
||||
* the state should be QSE_HTRE_COMPLETED. so only a
|
||||
* chunked request should reach here */
|
||||
QSE_ASSERT (arg->req->attr.flags & QSE_HTRE_ATTR_CHUNKED);
|
||||
QSE_ASSERT (arg->req->flags & QSE_HTRE_ATTR_CHUNKED);
|
||||
|
||||
proxy->reqflags |= PROXY_REQ_FWDCHUNKED;
|
||||
if (qse_mbs_cat (proxy->reqfwdbuf, QSE_MT("Transfer-Encoding: chunked\r\n")) == (qse_size_t)-1 ||
|
||||
|
@ -2087,7 +2087,7 @@ static int process_request (
|
||||
* any more. once it's decoded in the peek mode,
|
||||
* the decoded query path is made available in the
|
||||
* non-peek mode as well */
|
||||
if (peek) qse_perdechttpstr (qse_htre_getqpath(req), qse_htre_getqpath(req));
|
||||
if (peek) qse_htre_perdecqpath(req);
|
||||
|
||||
if (peek && (httpd->opt.trait & QSE_HTTPD_LOGACT))
|
||||
{
|
||||
@ -2154,11 +2154,11 @@ if (qse_htre_getcontentlen(req) > 0)
|
||||
else
|
||||
{
|
||||
if (mth == QSE_HTTP_POST &&
|
||||
!(req->attr.flags & QSE_HTRE_ATTR_LENGTH) &&
|
||||
!(req->attr.flags & QSE_HTRE_ATTR_CHUNKED))
|
||||
!(req->flags & QSE_HTRE_ATTR_LENGTH) &&
|
||||
!(req->flags & QSE_HTRE_ATTR_CHUNKED))
|
||||
{
|
||||
/* POST without Content-Length nor not chunked */
|
||||
req->attr.flags &= ~QSE_HTRE_ATTR_KEEPALIVE;
|
||||
req->flags &= ~QSE_HTRE_ATTR_KEEPALIVE;
|
||||
qse_httpd_discardcontent (httpd, req);
|
||||
task = qse_httpd_entaskerr (httpd, client, QSE_NULL, 411, req);
|
||||
if (task)
|
||||
@ -2234,7 +2234,7 @@ printf ("CANOT MAKE RESOURCE.... %s\n", qse_htre_getqpath(req));
|
||||
|
||||
if (task == QSE_NULL) goto oops;
|
||||
}
|
||||
else if (req->attr.flags & QSE_HTRE_ATTR_PROXIED)
|
||||
else if (req->flags & QSE_HTRE_ATTR_PROXIED)
|
||||
{
|
||||
/* the contents should be proxied.
|
||||
* do nothing locally */
|
||||
@ -2246,7 +2246,7 @@ printf ("CANOT MAKE RESOURCE.... %s\n", qse_htre_getqpath(req));
|
||||
}
|
||||
}
|
||||
|
||||
if (!(req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE) || mth == QSE_HTTP_CONNECT)
|
||||
if (!(req->flags & QSE_HTRE_ATTR_KEEPALIVE) || mth == QSE_HTTP_CONNECT)
|
||||
{
|
||||
if (!peek)
|
||||
{
|
||||
@ -2727,7 +2727,7 @@ static int make_resource (
|
||||
case QSE_HTTPD_SERVERSTD_ROOT_PROXY:
|
||||
target->type = QSE_HTTPD_RSRC_PROXY;
|
||||
target->u.proxy = tmp.root.u.proxy;
|
||||
req->attr.flags |= QSE_HTRE_ATTR_PROXIED;
|
||||
req->flags |= QSE_HTRE_ATTR_PROXIED;
|
||||
return 0;
|
||||
|
||||
case QSE_HTTPD_SERVERSTD_ROOT_ERROR:
|
||||
@ -2797,7 +2797,7 @@ auth_ok:
|
||||
|
||||
/* if authentication is ok or no authentication is required,
|
||||
* handle 'Expect: 100-continue' if it is contained in the header */
|
||||
if ((req->attr.flags & QSE_HTRE_ATTR_EXPECT) &&
|
||||
if ((req->flags & QSE_HTRE_ATTR_EXPECT) &&
|
||||
(req->version.major > 1 || (req->version.major == 1 && req->version.minor >= 1)) &&
|
||||
qse_htre_getcontentlen(req) <= 0)
|
||||
{
|
||||
@ -2807,7 +2807,7 @@ auth_ok:
|
||||
* if the partial or complete content is already received,
|
||||
* we don't need to send '100 continue'. */
|
||||
|
||||
if (req->attr.flags & QSE_HTRE_ATTR_EXPECT100)
|
||||
if (req->flags & QSE_HTRE_ATTR_EXPECT100)
|
||||
{
|
||||
/* "Expect: 100-continue" in the header.
|
||||
* mark to return "100 continue" */
|
||||
|
@ -242,7 +242,7 @@ qse_httpd_task_t* qse_httpd_entaskerr (
|
||||
httpd, client, pred, code, QSE_NULL,
|
||||
qse_htre_getqmethodtype(req),
|
||||
qse_htre_getversion(req),
|
||||
(req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE)
|
||||
(req->flags & QSE_HTRE_ATTR_KEEPALIVE)
|
||||
);
|
||||
}
|
||||
|
||||
@ -268,7 +268,7 @@ qse_httpd_task_t* qse_httpd_entaskauth (
|
||||
httpd, client, pred, 401, (void*)realm,
|
||||
qse_htre_getqmethodtype(req),
|
||||
qse_htre_getversion(req),
|
||||
(req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE));
|
||||
(req->flags & QSE_HTRE_ATTR_KEEPALIVE));
|
||||
}
|
||||
|
||||
|
||||
@ -287,7 +287,7 @@ qse_httpd_task_t* qse_httpd_entaskreloc (
|
||||
httpd, client, pred, 301, (void*)&reloc,
|
||||
qse_htre_getqmethodtype(req),
|
||||
qse_htre_getversion(req),
|
||||
(req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE));
|
||||
(req->flags & QSE_HTRE_ATTR_KEEPALIVE));
|
||||
}
|
||||
|
||||
qse_httpd_task_t* qse_httpd_entaskredir (
|
||||
@ -303,7 +303,7 @@ qse_httpd_task_t* qse_httpd_entaskredir (
|
||||
httpd, client, pred, 301, (void*)&reloc,
|
||||
qse_htre_getqmethodtype(req),
|
||||
qse_htre_getversion(req),
|
||||
(req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE));
|
||||
(req->flags & QSE_HTRE_ATTR_KEEPALIVE));
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
@ -324,7 +324,7 @@ qse_httpd_task_t* qse_httpd_entasknomod (
|
||||
httpd, client, pred, 304, QSE_NULL,
|
||||
qse_htre_getqmethodtype(req),
|
||||
qse_htre_getversion(req),
|
||||
(req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE));
|
||||
(req->flags & QSE_HTRE_ATTR_KEEPALIVE));
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
@ -340,7 +340,7 @@ qse_httpd_task_t* qse_httpd_entaskallow (
|
||||
|
||||
msg = qse_httpstatustombs (code);
|
||||
version = qse_htre_getversion(req);
|
||||
keepalive = (req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE);
|
||||
keepalive = (req->flags & QSE_HTRE_ATTR_KEEPALIVE);
|
||||
return qse_httpd_entaskformat (
|
||||
httpd, client, pred,
|
||||
QSE_MT("HTTP/%d.%d %d %s\r\nServer: %s\r\nDate: %s\r\nConnection: %s\r\nAllow: %s\r\nContent-Length: 0\r\n\r\n"),
|
||||
|
@ -112,7 +112,7 @@ qse_httpd_task_t* qse_httpd_entasktext (
|
||||
version->major, version->minor,
|
||||
qse_httpd_getname (httpd),
|
||||
qse_httpd_fmtgmtimetobb (httpd, QSE_NULL, 0),
|
||||
((req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE)? QSE_MT("keep-alive"): QSE_MT("close")),
|
||||
((req->flags & QSE_HTRE_ATTR_KEEPALIVE)? QSE_MT("keep-alive"): QSE_MT("close")),
|
||||
mime, b_tlen
|
||||
);
|
||||
if (pred == QSE_NULL) return QSE_NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user