changed the request inspection order for resource making
This commit is contained in:
parent
433b0da96d
commit
597824fc89
@ -100,6 +100,7 @@ struct qse_htre_t
|
|||||||
#define QSE_HTRE_ATTR_KEEPALIVE (1 << 2)
|
#define QSE_HTRE_ATTR_KEEPALIVE (1 << 2)
|
||||||
#define QSE_HTRE_ATTR_EXPECT (1 << 3)
|
#define QSE_HTRE_ATTR_EXPECT (1 << 3)
|
||||||
#define QSE_HTRE_ATTR_EXPECT100 (1 << 4)
|
#define QSE_HTRE_ATTR_EXPECT100 (1 << 4)
|
||||||
|
#define QSE_HTRE_ATTR_PROXIED (1 << 5)
|
||||||
int flags;
|
int flags;
|
||||||
qse_size_t content_length;
|
qse_size_t content_length;
|
||||||
const qse_mchar_t* status; /* for cgi */
|
const qse_mchar_t* status; /* for cgi */
|
||||||
|
@ -469,6 +469,11 @@ enum qse_httpd_rsrc_type_t
|
|||||||
};
|
};
|
||||||
typedef enum qse_httpd_rsrc_type_t qse_httpd_rsrc_type_t;
|
typedef enum qse_httpd_rsrc_type_t qse_httpd_rsrc_type_t;
|
||||||
|
|
||||||
|
enum qse_httpd_rsrc_flag_t
|
||||||
|
{
|
||||||
|
QSE_HTTPD_RSRC_100_CONTINUE = (1 << 0)
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct qse_httpd_rsrc_cgi_t qse_httpd_rsrc_cgi_t;
|
typedef struct qse_httpd_rsrc_cgi_t qse_httpd_rsrc_cgi_t;
|
||||||
struct qse_httpd_rsrc_cgi_t
|
struct qse_httpd_rsrc_cgi_t
|
||||||
{
|
{
|
||||||
@ -484,6 +489,7 @@ typedef struct qse_httpd_rsrc_t qse_httpd_rsrc_t;
|
|||||||
struct qse_httpd_rsrc_t
|
struct qse_httpd_rsrc_t
|
||||||
{
|
{
|
||||||
qse_httpd_rsrc_type_t type;
|
qse_httpd_rsrc_type_t type;
|
||||||
|
int flags; /**< bitwised-ORed of #qse_httpd_rsrc_flag_t */
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
|
@ -30,6 +30,7 @@ struct task_dir_t
|
|||||||
qse_mcstr_t qpath;
|
qse_mcstr_t qpath;
|
||||||
qse_http_version_t version;
|
qse_http_version_t version;
|
||||||
int keepalive;
|
int keepalive;
|
||||||
|
int headonly;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct task_dseg_t task_dseg_t;
|
typedef struct task_dseg_t task_dseg_t;
|
||||||
@ -457,6 +458,9 @@ qse_httpd_task_t* qse_httpd_entaskdir (
|
|||||||
{
|
{
|
||||||
qse_httpd_task_t task;
|
qse_httpd_task_t task;
|
||||||
task_dir_t data;
|
task_dir_t data;
|
||||||
|
int meth;
|
||||||
|
|
||||||
|
meth = qse_htre_getqmethodtype(req);
|
||||||
|
|
||||||
QSE_MEMSET (&data, 0, QSE_SIZEOF(data));
|
QSE_MEMSET (&data, 0, QSE_SIZEOF(data));
|
||||||
data.path.ptr = path;
|
data.path.ptr = path;
|
||||||
@ -466,6 +470,25 @@ qse_httpd_task_t* qse_httpd_entaskdir (
|
|||||||
data.version = *qse_htre_getversion(req);
|
data.version = *qse_htre_getversion(req);
|
||||||
data.keepalive = (req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE);
|
data.keepalive = (req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE);
|
||||||
|
|
||||||
|
switch (meth)
|
||||||
|
{
|
||||||
|
case QSE_HTTP_HEAD:
|
||||||
|
data.headonly = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QSE_HTTP_OPTIONS:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QSE_HTTP_GET:
|
||||||
|
case QSE_HTTP_POST:
|
||||||
|
case QSE_HTTP_PUT:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* Method not allowed */
|
||||||
|
return qse_httpd_entaskerr (httpd, client, pred, 405, req);
|
||||||
|
}
|
||||||
|
|
||||||
QSE_MEMSET (&task, 0, QSE_SIZEOF(task));
|
QSE_MEMSET (&task, 0, QSE_SIZEOF(task));
|
||||||
task.init = task_init_dir;
|
task.init = task_init_dir;
|
||||||
task.main = task_main_dir;
|
task.main = task_main_dir;
|
||||||
|
@ -36,6 +36,7 @@ struct task_file_t
|
|||||||
qse_ntime_t if_modified_since;
|
qse_ntime_t if_modified_since;
|
||||||
qse_http_version_t version;
|
qse_http_version_t version;
|
||||||
int keepalive;
|
int keepalive;
|
||||||
|
int headonly;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct task_fseg_t task_fseg_t;
|
typedef struct task_fseg_t task_fseg_t;
|
||||||
@ -234,6 +235,7 @@ static QSE_INLINE int task_main_file (
|
|||||||
);
|
);
|
||||||
if (x)
|
if (x)
|
||||||
{
|
{
|
||||||
|
if (file->headonly) goto no_file_send;
|
||||||
x = entask_file_segment (
|
x = entask_file_segment (
|
||||||
httpd, client, x,
|
httpd, client, x,
|
||||||
handle,
|
handle,
|
||||||
@ -288,7 +290,11 @@ static QSE_INLINE int task_main_file (
|
|||||||
qse_httpd_fmtgmtimetobb (httpd, &st.mtime, 1),
|
qse_httpd_fmtgmtimetobb (httpd, &st.mtime, 1),
|
||||||
etag
|
etag
|
||||||
);
|
);
|
||||||
if (x) x = entask_file_segment (httpd, client, x, handle, 0, st.size);
|
if (x)
|
||||||
|
{
|
||||||
|
if (file->headonly) goto no_file_send;
|
||||||
|
x = entask_file_segment (httpd, client, x, handle, 0, st.size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x) return 0;
|
if (x) return 0;
|
||||||
@ -311,6 +317,9 @@ qse_httpd_task_t* qse_httpd_entaskfile (
|
|||||||
qse_httpd_task_t task;
|
qse_httpd_task_t task;
|
||||||
task_file_t data;
|
task_file_t data;
|
||||||
const qse_htre_hdrval_t* tmp;
|
const qse_htre_hdrval_t* tmp;
|
||||||
|
int meth;
|
||||||
|
|
||||||
|
meth = qse_htre_getqmethodtype(req);;
|
||||||
|
|
||||||
QSE_MEMSET (&data, 0, QSE_SIZEOF(data));
|
QSE_MEMSET (&data, 0, QSE_SIZEOF(data));
|
||||||
data.path.ptr = path;
|
data.path.ptr = path;
|
||||||
@ -323,6 +332,25 @@ qse_httpd_task_t* qse_httpd_entaskfile (
|
|||||||
data.version = *qse_htre_getversion(req);
|
data.version = *qse_htre_getversion(req);
|
||||||
data.keepalive = (req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE);
|
data.keepalive = (req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE);
|
||||||
|
|
||||||
|
switch (meth)
|
||||||
|
{
|
||||||
|
case QSE_HTTP_HEAD:
|
||||||
|
data.headonly = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QSE_HTTP_OPTIONS:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QSE_HTTP_GET:
|
||||||
|
case QSE_HTTP_POST:
|
||||||
|
case QSE_HTTP_PUT:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* Method not allowed */
|
||||||
|
return qse_httpd_entaskerr (httpd, client, pred, 405, req);
|
||||||
|
}
|
||||||
|
|
||||||
tmp = qse_htre_getheaderval(req, QSE_MT("Range"));
|
tmp = qse_htre_getheaderval(req, QSE_MT("Range"));
|
||||||
if (tmp)
|
if (tmp)
|
||||||
{
|
{
|
||||||
|
@ -1826,18 +1826,13 @@ qse_printf (QSE_T("HEADER OK %d[%hs] %d[%hs]\n"), (int)QSE_HTB_KLEN(pair), QSE_
|
|||||||
static int process_request (
|
static int process_request (
|
||||||
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_htre_t* req, int peek)
|
qse_httpd_t* httpd, qse_httpd_client_t* client, qse_htre_t* req, int peek)
|
||||||
{
|
{
|
||||||
int method;
|
|
||||||
qse_httpd_task_t* task;
|
qse_httpd_task_t* task;
|
||||||
int content_received;
|
|
||||||
server_xtn_t* server_xtn;
|
server_xtn_t* server_xtn;
|
||||||
|
|
||||||
server_xtn = (server_xtn_t*)qse_httpd_getserverxtn (httpd, client->server);
|
server_xtn = (server_xtn_t*)qse_httpd_getserverxtn (httpd, client->server);
|
||||||
|
|
||||||
method = qse_htre_getqmethodtype(req);
|
|
||||||
content_received = (qse_htre_getcontentlen(req) > 0);
|
|
||||||
|
|
||||||
/* percent-decode the query path to the original buffer
|
/* percent-decode the query path to the original buffer
|
||||||
* since i'm not gonna need it in the original form
|
* since i'm not going to need it in the original form
|
||||||
* any more. once it's decoded in the peek mode,
|
* any more. once it's decoded in the peek mode,
|
||||||
* the decoded query path is made available in the
|
* the decoded query path is made available in the
|
||||||
* non-peek mode as well */
|
* non-peek mode as well */
|
||||||
@ -1864,54 +1859,20 @@ if (qse_htre_getcontentlen(req) > 0)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (peek)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
if (method == QSE_HTTP_HEAD || method == QSE_HTTP_GET)
|
|
||||||
{
|
|
||||||
/* i'll discard request contents if the method is HEAD or GET */
|
|
||||||
qse_httpd_discardcontent (httpd, req);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if ((req->attr.flags & QSE_HTRE_ATTR_EXPECT) &&
|
|
||||||
(req->version.major > 1 ||
|
|
||||||
(req->version.major == 1 && req->version.minor >= 1)) &&
|
|
||||||
!content_received)
|
|
||||||
{
|
|
||||||
int code;
|
|
||||||
|
|
||||||
/* "Expect" in the header, version 1.1 or higher,
|
|
||||||
* and no content received yet.
|
|
||||||
* 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)
|
|
||||||
{
|
|
||||||
/* "Expect: 100-continue" in the header */
|
|
||||||
if (qse_httpd_entaskcontinue (httpd, client, QSE_NULL, req) == QSE_NULL) return -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* if expectation fails, the client must not send the contents.
|
|
||||||
* however, some erroneous clients may do that.
|
|
||||||
* calling qse_httpd_discardcontent() won't do any harms */
|
|
||||||
qse_httpd_discardcontent (httpd, req);
|
|
||||||
task = qse_httpd_entaskerr (httpd, client, QSE_NULL, 417, req);
|
|
||||||
if (task == QSE_NULL) goto oops;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (method == QSE_HTTP_GET || method == QSE_HTTP_POST)
|
|
||||||
{
|
|
||||||
if (peek)
|
if (peek)
|
||||||
{
|
{
|
||||||
qse_httpd_rsrc_t rsrc;
|
qse_httpd_rsrc_t rsrc;
|
||||||
|
|
||||||
if (method == QSE_HTTP_POST &&
|
/* determine what to do once the header fields are all received.
|
||||||
|
* i don't want to delay this until the contents are received.
|
||||||
|
* if you don't like this behavior, you must implement your own
|
||||||
|
* callback function for request handling. */
|
||||||
|
|
||||||
|
if (qse_htre_getqmethodtype(req) == QSE_HTTP_POST &&
|
||||||
!(req->attr.flags & QSE_HTRE_ATTR_LENGTH) &&
|
!(req->attr.flags & QSE_HTRE_ATTR_LENGTH) &&
|
||||||
!(req->attr.flags & QSE_HTRE_ATTR_CHUNKED))
|
!(req->attr.flags & QSE_HTRE_ATTR_CHUNKED))
|
||||||
{
|
{
|
||||||
|
/* POST without Content-Length nor not chunked */
|
||||||
req->attr.flags &= ~QSE_HTRE_ATTR_KEEPALIVE;
|
req->attr.flags &= ~QSE_HTRE_ATTR_KEEPALIVE;
|
||||||
qse_httpd_discardcontent (httpd, req);
|
qse_httpd_discardcontent (httpd, req);
|
||||||
task = qse_httpd_entaskerr (httpd, client, QSE_NULL, 411, req);
|
task = qse_httpd_entaskerr (httpd, client, QSE_NULL, 411, req);
|
||||||
@ -1923,27 +1884,45 @@ if (qse_htre_getcontentlen(req) > 0)
|
|||||||
}
|
}
|
||||||
else if (server_xtn->makersrc (httpd, client, req, &rsrc) <= -1)
|
else if (server_xtn->makersrc (httpd, client, req, &rsrc) <= -1)
|
||||||
{
|
{
|
||||||
|
/* failed to make a resource. just send the internal server error.
|
||||||
|
* the makersrc handler can return a negative number to return
|
||||||
|
* '500 Internal Server Error'. If it wants to return a specific
|
||||||
|
* error code, it should return 0 with the QSE_HTTPD_RSRC_ERR
|
||||||
|
* resource. */
|
||||||
qse_httpd_discardcontent (httpd, req);
|
qse_httpd_discardcontent (httpd, req);
|
||||||
task = qse_httpd_entaskerr (httpd, client, QSE_NULL, 500, req);
|
task = qse_httpd_entaskerr (httpd, client, QSE_NULL, 500, req);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
task = qse_httpd_entaskrsrc (httpd, client, QSE_NULL, &rsrc, req);
|
task = QSE_NULL;
|
||||||
|
|
||||||
|
/* inject '100 continue' first if it is needed */
|
||||||
|
if ((rsrc.flags & QSE_HTTPD_RSRC_100_CONTINUE) &&
|
||||||
|
(task = qse_httpd_entaskcontinue (httpd, client, task, req)) == QSE_NULL) goto oops;
|
||||||
|
|
||||||
|
/* arrange the actual resource to be returned */
|
||||||
|
task = qse_httpd_entaskrsrc (httpd, client, task, &rsrc, req);
|
||||||
server_xtn->freersrc (httpd, client, req, &rsrc);
|
server_xtn->freersrc (httpd, client, req, &rsrc);
|
||||||
|
|
||||||
|
/* if the resource is indicating to return an error,
|
||||||
|
* discard the contents since i won't return them */
|
||||||
|
if (rsrc.type == QSE_HTTPD_RSRC_ERR) qse_httpd_discardcontent (httpd, req);
|
||||||
}
|
}
|
||||||
if (task == QSE_NULL) goto oops;
|
if (task == QSE_NULL) goto oops;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* contents are all received */
|
||||||
|
|
||||||
|
if (req->attr.flags & QSE_HTRE_ATTR_PROXIED)
|
||||||
|
{
|
||||||
|
/* the contents should be proxied.
|
||||||
|
* do nothing locally */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (peek)
|
/* when the request is handled locally,
|
||||||
{
|
* there's nothing special to do here */
|
||||||
qse_httpd_discardcontent (httpd, req);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
task = qse_httpd_entaskerr (httpd, client, QSE_NULL, 405, req);
|
|
||||||
if (task == QSE_NULL) goto oops;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2435,7 +2414,7 @@ static int make_resource (
|
|||||||
struct rsrc_tmp_t tmp;
|
struct rsrc_tmp_t tmp;
|
||||||
|
|
||||||
qse_httpd_stat_t st;
|
qse_httpd_stat_t st;
|
||||||
int n, stx;
|
int n, stx, meth;
|
||||||
|
|
||||||
QSE_MEMSET (&tmp, 0, QSE_SIZEOF(tmp));
|
QSE_MEMSET (&tmp, 0, QSE_SIZEOF(tmp));
|
||||||
tmp.qpath = qse_htre_getqpath(req);
|
tmp.qpath = qse_htre_getqpath(req);
|
||||||
@ -2445,7 +2424,7 @@ static int make_resource (
|
|||||||
|
|
||||||
server_xtn = qse_httpd_getserverxtn (httpd, client->server);
|
server_xtn = qse_httpd_getserverxtn (httpd, client->server);
|
||||||
|
|
||||||
if (server_xtn->query (httpd, client->server, req, tmp.xpath, QSE_HTTPD_SERVERSTD_ROOT, &tmp.root) <= -1) return -1;
|
if (server_xtn->query (httpd, client->server, req, QSE_NULL, QSE_HTTPD_SERVERSTD_ROOT, &tmp.root) <= -1) return -1;
|
||||||
if (tmp.root.type == QSE_HTTPD_SERVERSTD_ROOT_NWAD)
|
if (tmp.root.type == QSE_HTTPD_SERVERSTD_ROOT_NWAD)
|
||||||
{
|
{
|
||||||
/* proxy the request */
|
/* proxy the request */
|
||||||
@ -2453,13 +2432,30 @@ static int make_resource (
|
|||||||
/*target->u.proxy.dst = client->orgdst_addr;*/
|
/*target->u.proxy.dst = client->orgdst_addr;*/
|
||||||
target->u.proxy.dst = tmp.root.u.nwad;
|
target->u.proxy.dst = tmp.root.u.nwad;
|
||||||
target->u.proxy.src = client->remote_addr;
|
target->u.proxy.src = client->remote_addr;
|
||||||
|
|
||||||
|
/* mark that this request is going to be proxied. */
|
||||||
|
req->attr.flags |= QSE_HTRE_ATTR_PROXIED;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* handle the request locally */
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
meth = qse_htre_getqmethodtype(req);
|
||||||
|
if (meth != QSE_HTTP_GET && meth != QSE_HTTP_POST && meth != QSE_HTTP_PUT && method != QSE_HTTP_)
|
||||||
|
{
|
||||||
|
/* TODO: handle more method types */
|
||||||
|
/* method not allowed */
|
||||||
|
target->type = QSE_HTTPD_RSRC_ERR;
|
||||||
|
target->u.err.code = 405;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
QSE_ASSERT (tmp.root.type == QSE_HTTPD_SERVERSTD_ROOT_PATH);
|
QSE_ASSERT (tmp.root.type == QSE_HTTPD_SERVERSTD_ROOT_PATH);
|
||||||
|
|
||||||
if (server_xtn->query (httpd, client->server, req, tmp.xpath, QSE_HTTPD_SERVERSTD_REALM, &tmp.realm) <= -1 ||
|
if (server_xtn->query (httpd, client->server, req, QSE_NULL, QSE_HTTPD_SERVERSTD_REALM, &tmp.realm) <= -1 ||
|
||||||
server_xtn->query (httpd, client->server, req, tmp.xpath, QSE_HTTPD_SERVERSTD_INDEX, &tmp.index) <= -1)
|
server_xtn->query (httpd, client->server, req, QSE_NULL, QSE_HTTPD_SERVERSTD_INDEX, &tmp.index) <= -1)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -2477,7 +2473,7 @@ static int make_resource (
|
|||||||
authv = qse_htre_getheaderval (req, QSE_MT("Authorization"));
|
authv = qse_htre_getheaderval (req, QSE_MT("Authorization"));
|
||||||
if (authv)
|
if (authv)
|
||||||
{
|
{
|
||||||
while (authv->next) authv = authv->next;
|
/*while (authv->next) authv = authv->next;*/
|
||||||
|
|
||||||
if (qse_mbszcasecmp(authv->ptr, QSE_MT("Basic "), 6) == 0)
|
if (qse_mbszcasecmp(authv->ptr, QSE_MT("Basic "), 6) == 0)
|
||||||
{
|
{
|
||||||
@ -2488,11 +2484,11 @@ static int make_resource (
|
|||||||
authl = qse_mbslen(&authv->ptr[6]);
|
authl = qse_mbslen(&authv->ptr[6]);
|
||||||
if (authl > server_xtn->auth.len)
|
if (authl > server_xtn->auth.len)
|
||||||
{
|
{
|
||||||
qse_mchar_t* tmp;
|
qse_mchar_t* tptr;
|
||||||
tmp = qse_httpd_reallocmem (httpd, server_xtn->auth.ptr, authl * QSE_SIZEOF(qse_mchar_t));
|
tptr = qse_httpd_reallocmem (httpd, server_xtn->auth.ptr, authl * QSE_SIZEOF(qse_mchar_t));
|
||||||
if (!tmp) return -1;
|
if (!tptr) return -1;
|
||||||
|
|
||||||
server_xtn->auth.ptr = tmp;
|
server_xtn->auth.ptr = tptr;
|
||||||
/* the maximum capacity that can hold the largest authorization value */
|
/* the maximum capacity that can hold the largest authorization value */
|
||||||
server_xtn->auth.len = authl;
|
server_xtn->auth.len = authl;
|
||||||
}
|
}
|
||||||
@ -2503,7 +2499,7 @@ static int make_resource (
|
|||||||
|
|
||||||
tmp.auth.key.ptr = server_xtn->auth.ptr;
|
tmp.auth.key.ptr = server_xtn->auth.ptr;
|
||||||
tmp.auth.key.len = authl2;
|
tmp.auth.key.len = authl2;
|
||||||
if (server_xtn->query (httpd, client->server, req, tmp.xpath, QSE_HTTPD_SERVERSTD_AUTH, &tmp.auth) >= 0 && tmp.auth.authok) goto auth_ok;
|
if (server_xtn->query (httpd, client->server, req, QSE_NULL, QSE_HTTPD_SERVERSTD_AUTH, &tmp.auth) >= 0 && tmp.auth.authok) goto auth_ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2513,6 +2509,34 @@ static int make_resource (
|
|||||||
}
|
}
|
||||||
|
|
||||||
auth_ok:
|
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) &&
|
||||||
|
(req->version.major > 1 || (req->version.major == 1 && req->version.minor >= 1)) &&
|
||||||
|
qse_htre_getcontentlen(req) <= 0)
|
||||||
|
{
|
||||||
|
/* "Expect" in the header, version 1.1 or higher,
|
||||||
|
* and no content received yet. don't care about the method type.
|
||||||
|
*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
/* "Expect: 100-continue" in the header.
|
||||||
|
* mark to return "100 continue" */
|
||||||
|
target->flags |= QSE_HTTPD_RSRC_100_CONTINUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Expectation Failed */
|
||||||
|
target->type = QSE_HTTPD_RSRC_ERR;
|
||||||
|
target->u.err.code = 417;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tmp.xpath = merge_paths (httpd, tmp.root.u.path.val, tmp.qpath_rp);
|
tmp.xpath = merge_paths (httpd, tmp.root.u.path.val, tmp.qpath_rp);
|
||||||
if (tmp.xpath == QSE_NULL) return -1;
|
if (tmp.xpath == QSE_NULL) return -1;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user