From 595e3be04346c1eb0c8a549283f4de101bcfa71c Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Tue, 26 Mar 2013 16:29:26 +0000 Subject: [PATCH] added some code for handling the PUT method --- qse/lib/http/httpd-dir.c | 5 +- qse/lib/http/httpd-file.c | 331 +++++++++++++++++++++++++++++++------ qse/lib/http/httpd-proxy.c | 49 +++--- qse/lib/http/httpd-std.c | 32 ++-- qse/lib/http/httpd-task.c | 4 +- 5 files changed, 326 insertions(+), 95 deletions(-) diff --git a/qse/lib/http/httpd-dir.c b/qse/lib/http/httpd-dir.c index 540df7b3..86199c25 100644 --- a/qse/lib/http/httpd-dir.c +++ b/qse/lib/http/httpd-dir.c @@ -470,15 +470,14 @@ qse_httpd_task_t* qse_httpd_entaskdir ( data.version = *qse_htre_getversion(req); data.keepalive = (req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE); + + qse_htre_discardcontent (req); /* TODO: don't discard for put??? */ 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: diff --git a/qse/lib/http/httpd-file.c b/qse/lib/http/httpd-file.c index 08573b38..7ab70430 100644 --- a/qse/lib/http/httpd-file.c +++ b/qse/lib/http/httpd-file.c @@ -25,50 +25,68 @@ #define ETAG_LEN_MAX 127 +#define PUTFILE_INIT_FAILED (1 << 0) + typedef struct task_file_t task_file_t; struct task_file_t { qse_mcstr_t path; - qse_mcstr_t mime; qse_http_range_t range; qse_mchar_t if_none_match[ETAG_LEN_MAX + 1]; qse_ntime_t if_modified_since; qse_http_version_t version; int keepalive; - int headonly; + int method; + + /* only for put file... */ + union + { + struct + { + qse_mcstr_t mime; + } get; + struct + { + int flags; + qse_htre_t* req; + qse_ubi_t handle; + } put; + } u; }; -typedef struct task_fseg_t task_fseg_t; -struct task_fseg_t +/*------------------------------------------------------------------------*/ + +typedef struct task_getfseg_t task_getfseg_t; +struct task_getfseg_t { qse_ubi_t handle; qse_foff_t left; qse_foff_t offset; }; -static int task_init_fseg ( +static int task_init_getfseg ( qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) { - task_fseg_t* xtn = qse_httpd_gettaskxtn (httpd, task); + task_getfseg_t* xtn = qse_httpd_gettaskxtn (httpd, task); QSE_MEMCPY (xtn, task->ctx, QSE_SIZEOF(*xtn)); task->ctx = xtn; return 0; } -static void task_fini_fseg ( +static void task_fini_getfseg ( qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) { - task_fseg_t* ctx = (task_fseg_t*)task->ctx; + task_getfseg_t* ctx = (task_getfseg_t*)task->ctx; httpd->opt.scb.file.close (httpd, ctx->handle); } -static int task_main_fseg ( +static int task_main_getfseg ( qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) { qse_ssize_t n; qse_size_t count; - task_fseg_t* ctx = (task_fseg_t*)task->ctx; + task_getfseg_t* ctx = (task_getfseg_t*)task->ctx; count = MAX_SEND_SIZE; if (count >= ctx->left) count = ctx->left; @@ -98,13 +116,13 @@ static int task_main_fseg ( return 1; /* more work to do */ } -static qse_httpd_task_t* entask_file_segment ( +static qse_httpd_task_t* entask_getfseg ( qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* pred, qse_ubi_t handle, qse_foff_t offset, qse_foff_t size) { qse_httpd_task_t task; - task_fseg_t data; + task_getfseg_t data; QSE_MEMSET (&data, 0, QSE_SIZEOF(data)); data.handle = handle; @@ -112,9 +130,9 @@ static qse_httpd_task_t* entask_file_segment ( data.left = size; QSE_MEMSET (&task, 0, QSE_SIZEOF(task)); - task.init = task_init_fseg; - task.main = task_main_fseg; - task.fini = task_fini_fseg; + task.init = task_init_getfseg; + task.main = task_main_getfseg; + task.fini = task_fini_getfseg; task.ctx = &data; return qse_httpd_entask (httpd, client, pred, &task, QSE_SIZEOF(data)); @@ -123,7 +141,7 @@ static qse_httpd_task_t* entask_file_segment ( /*------------------------------------------------------------------------*/ -static int task_init_file ( +static int task_init_getfile ( qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) { task_file_t* file = qse_httpd_gettaskxtn (httpd, task); @@ -133,17 +151,17 @@ static int task_init_file ( file->path.ptr = (qse_mchar_t*)(file + 1); qse_mbscpy ((qse_mchar_t*)file->path.ptr, arg->path.ptr); - if (arg->mime.ptr) + if (arg->u.get.mime.ptr) { - file->mime.ptr = file->path.ptr + file->path.len + 1; - qse_mbscpy ((qse_mchar_t*)file->mime.ptr, arg->mime.ptr); + file->u.get.mime.ptr = file->path.ptr + file->path.len + 1; + qse_mbscpy ((qse_mchar_t*)file->u.get.mime.ptr, arg->u.get.mime.ptr); } task->ctx = file; return 0; } -static QSE_INLINE int task_main_file ( +static QSE_INLINE int task_main_getfile ( qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) { task_file_t* file; @@ -228,15 +246,15 @@ static QSE_INLINE int task_main_file ( qse_httpd_getname (httpd), qse_httpd_fmtgmtimetobb (httpd, QSE_NULL, 0), (file->keepalive? QSE_MT("keep-alive"): QSE_MT("close")), - (file->mime.len > 0? QSE_MT("Content-Type: "): QSE_MT("")), - (file->mime.len > 0? file->mime.ptr: QSE_MT("")), - (file->mime.len > 0? QSE_MT("\r\n"): QSE_MT("")), + (file->u.get.mime.len > 0? QSE_MT("Content-Type: "): QSE_MT("")), + (file->u.get.mime.len > 0? file->u.get.mime.ptr: QSE_MT("")), + (file->u.get.mime.len > 0? QSE_MT("\r\n"): QSE_MT("")), tmp[0], tmp[1], tmp[2], tmp[3], etag ); if (x) { - if (file->headonly) goto no_file_send; - x = entask_file_segment ( + if (file->method == QSE_HTTP_HEAD) goto no_file_send; + x = entask_getfseg ( httpd, client, x, handle, file->range.from, @@ -283,17 +301,17 @@ static QSE_INLINE int task_main_file ( qse_httpd_getname (httpd), qse_httpd_fmtgmtimetobb (httpd, QSE_NULL, 0), (file->keepalive? QSE_MT("keep-alive"): QSE_MT("close")), - (file->mime.len > 0? QSE_MT("Content-Type: "): QSE_MT("")), - (file->mime.len > 0? file->mime.ptr: QSE_MT("")), - (file->mime.len > 0? QSE_MT("\r\n"): QSE_MT("")), + (file->u.get.mime.len > 0? QSE_MT("Content-Type: "): QSE_MT("")), + (file->u.get.mime.len > 0? file->u.get.mime.ptr: QSE_MT("")), + (file->u.get.mime.len > 0? QSE_MT("\r\n"): QSE_MT("")), b_fsize, qse_httpd_fmtgmtimetobb (httpd, &st.mtime, 1), etag ); if (x) { - if (file->headonly) goto no_file_send; - x = entask_file_segment (httpd, client, x, handle, 0, st.size); + if (file->method == QSE_HTTP_HEAD) goto no_file_send; + x = entask_getfseg (httpd, client, x, handle, 0, st.size); } } @@ -306,6 +324,205 @@ no_file_send: return (x == QSE_NULL)? -1: 0; } +/*------------------------------------------------------------------------*/ + +static int putfile_snatch_client_input ( + qse_htre_t* req, const qse_mchar_t* ptr, qse_size_t len, void* ctx) +{ + qse_httpd_task_t* task; + task_file_t* file; + + task = (qse_httpd_task_t*)ctx; + file = (task_file_t*)task->ctx; + + if (ptr == QSE_NULL) + { + /* + * this callback is called with ptr of QSE_NULL + * when the request is completed or discarded. + * and this indicates that there's nothing more to read + * from the client side. this can happen when the end of + * a request is seen or when an error occurs + */ + QSE_ASSERT (len == 0); + + /* mark the there's nothing to read form the client side */ + qse_htre_unsetconcb (file->u.put.req); + file->u.put.req = QSE_NULL; + + /* since there is no more to read from the client side. + * the trigger is not needed any more. */ + task->trigger[0].mask = 0; + } + else /*if (!(file->reqflags & PROXY_REQ_FWDERR))*/ + { + /* TODO: write to file */ +qse_printf (QSE_T("WRITING 4 [%.*hs]\n"), (int)len, ptr); + } + + return 0; +} + +static int task_init_putfile ( + qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) +{ + task_file_t* file = qse_httpd_gettaskxtn (httpd, task); + task_file_t* arg = (task_file_t*)task->ctx; + int snatch_needed; + + /* zero out the task's extension area */ + QSE_MEMCPY (file, arg, QSE_SIZEOF(*file)); + file->u.put.req = QSE_NULL; + + /* copy in the path name to the area */ + file->path.ptr = (qse_mchar_t*)(file + 1); + qse_mbscpy ((qse_mchar_t*)file->path.ptr, arg->path.ptr); + + snatch_needed = 0; + +#if 0 + httpd->errnum = QSE_HTTPD_ENOERR; + if (httpd->opt.scb.file.stat (httpd, file->path.ptr, &st) <= -1) + { + int http_errnum = 500; + + switch (httpd->errnum) + { + case QSE_HTTPD_ENOENT: + /* nothing to do */ + break; + + case QSE_HTTPD_EACCES: + http_errnum = 403; + default: + + goto no_file_write; + } + } +#endif + + if (httpd->opt.scb.file.wopen (httpd, file->path.ptr, &file->u.put.handle) <= -1) goto oops; + + if (arg->u.put.req->state & QSE_HTRE_DISCARDED) + { + /* no content to add */ +/* TODO: return what??? */ +qse_printf (QSE_T("ALL DISCARDED...\n")); + } + else if (arg->u.put.req->state & QSE_HTRE_COMPLETED) + { +#if 0 + len = qse_htre_getcontentlen(arg->u.put.req); + if (len > 0) + { + ptr = qse_htre_getcontentptr(arg->u.put.req); + /* TODO: write this to a file */ + } +#endif +qse_printf (QSE_T("WRITING 1 [%.*hs]\n"), (int)qse_htre_getcontentlen(arg->u.put.req), qse_htre_getcontentptr(arg->u.put.req)); + } + else if (arg->u.put.req->attr.flags & QSE_HTRE_ATTR_LENGTH) + { + /* Content-Length is included and the content + * has been received partially so far */ + +#if 0 + len = qse_htre_getcontentlen(arg->u.put.req); + if (len > 0) + { + ptr = qse_htre_getcontentptr(arg->u.put.req); + /* TODO: write to a file */ + } + +#endif +qse_printf (QSE_T("WRITING 2 [%.*hs]\n"), (int)qse_htre_getcontentlen(arg->u.put.req), qse_htre_getcontentptr(arg->u.put.req)); + snatch_needed = 1; + } + else + { + /* 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->u.put.req->attr.flags & QSE_HTRE_ATTR_CHUNKED); + +qse_printf (QSE_T("WRITING 3 [%.*hs]\n"), (int)qse_htre_getcontentlen(arg->u.put.req), qse_htre_getcontentptr(arg->u.put.req)); +#if 0 + len = qse_htre_getcontentlen(arg->u.put.req); + if (len > 0) + { + ptr = qse_htre_getcontentptr(arg->u.put.req); + } +#endif + + snatch_needed = 1; + } + + if (snatch_needed) + { + /* set up a callback to be called when the request content + * is fed to the htrd reader. qse_htre_addcontent() that + * htrd calls invokes this callback. */ + file->u.put.req = arg->u.put.req; + qse_htre_setconcb (file->u.put.req, putfile_snatch_client_input, task); + } + + /* no triggers yet since the main loop doesn't allow me to set + * triggers in the task initializer. however the main task handler + * will be invoked so long as the client handle is writable by + * the main loop. */ + + task->ctx = file; /* switch the task context to the extension area */ + return 0; + +oops: + /* since a new task can't be added in the initializer, + * i mark that initialization failed and let task_main_putfile() + * add an error task */ + file->u.put.flags |= PUTFILE_INIT_FAILED; + task->ctx = file; + return 0; +} + +static void task_fini_putfile ( + qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) +{ + task_file_t* file = (task_file_t*)task->ctx; + +qse_printf (QSE_T("put fini....\n")); + if (!(file->u.put.flags & PUTFILE_INIT_FAILED)) + httpd->opt.scb.file.close (httpd, file->u.put.handle); +} + +static int task_main_putfile ( + qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) +{ + task_file_t* file = (task_file_t*)task->ctx; +qse_printf (QSE_T("put main....\n")); + + if (file->u.put.req) + { +qse_printf (QSE_T("put xxxxx....\n")); + /* still snatching the content body */ + task->trigger[0].mask = QSE_HTTPD_TASK_TRIGGER_READ; + task->trigger[0].handle = client->handle; + return 1; + } + +qse_printf (QSE_T("put what....\n")); + return 0; +} + +/*------------------------------------------------------------------------*/ + +static QSE_INLINE int task_main_delfile ( + qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* task) +{ + /* TODO: implement this */ + return -1; +} + +/*------------------------------------------------------------------------*/ + qse_httpd_task_t* qse_httpd_entaskfile ( qse_httpd_t* httpd, qse_httpd_client_t* client, @@ -317,35 +534,50 @@ qse_httpd_task_t* qse_httpd_entaskfile ( qse_httpd_task_t task; task_file_t data; const qse_htre_hdrval_t* tmp; - int meth; - - meth = qse_htre_getqmethodtype(req);; + qse_size_t xtnsize; QSE_MEMSET (&data, 0, QSE_SIZEOF(data)); data.path.ptr = path; data.path.len = qse_mbslen(path); - if (mime) - { - data.mime.ptr = mime; - data.mime.len = qse_mbslen(mime); - } data.version = *qse_htre_getversion(req); data.keepalive = (req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE); + data.method = qse_htre_getqmethodtype(req); - switch (meth) + xtnsize = QSE_SIZEOF(task_file_t) + data.path.len + 1; + + QSE_MEMSET (&task, 0, QSE_SIZEOF(task)); + + switch (data.method) { 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: + qse_htre_discardcontent (req); + + if (mime) + { + data.u.get.mime.ptr = mime; + data.u.get.mime.len = qse_mbslen(mime); + xtnsize += data.u.get.mime.len + 1; + } + + task.init = task_init_getfile; + task.main = task_main_getfile; break; + case QSE_HTTP_PUT: + data.u.put.req = req; + task.init = task_init_putfile; + task.main = task_main_putfile; + task.fini = task_fini_putfile; + break; + +#if 0 + case QSE_HTTP_DELETE: + task.main = task_main_delfile; + break; +#endif + default: /* Method not allowed */ return qse_httpd_entaskerr (httpd, client, pred, 405, req); @@ -395,12 +627,7 @@ qse_httpd_task_t* qse_httpd_entaskfile ( } } - QSE_MEMSET (&task, 0, QSE_SIZEOF(task)); - task.init = task_init_file; - task.main = task_main_file; task.ctx = &data; - - return qse_httpd_entask (httpd, client, pred, &task, - QSE_SIZEOF(task_file_t) + data.path.len + 1 + data.mime.len + 1); + return qse_httpd_entask (httpd, client, pred, &task, xtnsize); } diff --git a/qse/lib/http/httpd-proxy.c b/qse/lib/http/httpd-proxy.c index 9e98210f..d3a8a8b2 100644 --- a/qse/lib/http/httpd-proxy.c +++ b/qse/lib/http/httpd-proxy.c @@ -350,9 +350,11 @@ static int proxy_htrd_peek_peer_output (qse_htrd_t* htrd, qse_htre_t* res) { proxy_peer_htrd_xtn_t* xtn; task_proxy_t* proxy; + qse_httpd_t* httpd; xtn = (proxy_peer_htrd_xtn_t*) qse_htrd_getxtn (htrd); proxy = xtn->proxy; + httpd = proxy->httpd; QSE_ASSERT (!(res->state & QSE_HTRE_DISCARDED)); @@ -361,7 +363,7 @@ static int proxy_htrd_peek_peer_output (qse_htrd_t* htrd, qse_htre_t* res) /* this peek handler is being called again. * this can happen if qse_htrd_feed() is fed with * multiple responses in task_main_proxy_2 (). */ - proxy->httpd->errnum = QSE_HTTPD_EINVAL; + httpd->errnum = QSE_HTTPD_EINVAL; return -1; } @@ -380,7 +382,7 @@ static int proxy_htrd_peek_peer_output (qse_htrd_t* htrd, qse_htre_t* res) qse_mbs_cat (proxy->res, qse_htre_getsmesg(res)) == (qse_size_t)-1 || qse_mbs_cat (proxy->res, QSE_MT("\r\n\r\n")) == (qse_size_t)-1) { - proxy->httpd->errnum = QSE_HTTPD_ENOMEM; + httpd->errnum = QSE_HTTPD_ENOMEM; return -1; } @@ -397,10 +399,6 @@ static int proxy_htrd_peek_peer_output (qse_htrd_t* htrd, qse_htre_t* res) proxy->resflags &= ~PROXY_RES_AWAIT_RESHDR; proxy->resflags |= PROXY_RES_RECEIVED_RESHDR; -#if 0 -qse_printf (QSE_T("NORMAL REPLY 222222222222222222222 NORMAL REPLY\n")); -#endif - keepalive = proxy->keepalive; if (res->attr.flags & QSE_HTRE_ATTR_LENGTH) { @@ -448,7 +446,7 @@ qse_printf (QSE_T("NORMAL REPLY 222222222222222222222 NORMAL REPLY\n")); /* mark that the connection to client should be closed */ proxy->resflags |= PROXY_RES_CLIENT_DISCON; /* and push the actual disconnection task */ - if (qse_httpd_entaskdisconnect (proxy->httpd, xtn->client, xtn->task) == QSE_NULL) return -1; + if (qse_httpd_entaskdisconnect (httpd, xtn->client, xtn->task) == QSE_NULL) return -1; if (res->attr.flags & QSE_HTRE_ATTR_CHUNKED) proxy->resflags |= PROXY_RES_PEER_CHUNK; @@ -471,7 +469,7 @@ qse_printf (QSE_T("NORMAL REPLY 222222222222222222222 NORMAL REPLY\n")); qse_mbs_cat (proxy->res, QSE_MT(".")) == (qse_size_t)-1 || qse_mbs_cat (proxy->res, minor) == (qse_size_t)-1) { - proxy->httpd->errnum = QSE_HTTPD_ENOMEM; + httpd->errnum = QSE_HTTPD_ENOMEM; return -1; } } @@ -479,7 +477,7 @@ qse_printf (QSE_T("NORMAL REPLY 222222222222222222222 NORMAL REPLY\n")); { if (qse_mbs_cat (proxy->res, qse_htre_getverstr(res)) == (qse_size_t)-1) { - proxy->httpd->errnum = QSE_HTTPD_ENOMEM; + httpd->errnum = QSE_HTTPD_ENOMEM; return -1; } } @@ -490,19 +488,19 @@ qse_printf (QSE_T("NORMAL REPLY 222222222222222222222 NORMAL REPLY\n")); qse_mbs_cat (proxy->res, qse_htre_getsmesg(res)) == (qse_size_t)-1 || qse_mbs_cat (proxy->res, QSE_MT("\r\n")) == (qse_size_t)-1) { - proxy->httpd->errnum = QSE_HTTPD_ENOMEM; + httpd->errnum = QSE_HTTPD_ENOMEM; return -1; } /* end initial line */ - if (!(proxy->httpd->opt.trait & QSE_HTTPD_PROXYNOVIA) && qse_htre_getscodeval(res) != 100) + if (!(httpd->opt.trait & QSE_HTTPD_PROXYNOVIA) && qse_htre_getscodeval(res) != 100) { /* add the Via: header into the response if it is not 100. */ if (qse_mbs_cat (proxy->res, QSE_MT("Via: ")) == (qse_size_t)-1 || - qse_mbs_cat (proxy->res, qse_httpd_getname (proxy->httpd)) == (qse_size_t)-1 || + qse_mbs_cat (proxy->res, qse_httpd_getname (httpd)) == (qse_size_t)-1 || qse_mbs_cat (proxy->res, QSE_MT("\r\n")) == (qse_size_t)-1) { - proxy->httpd->errnum = QSE_HTTPD_ENOMEM; + httpd->errnum = QSE_HTTPD_ENOMEM; return -1; } } @@ -523,7 +521,7 @@ qse_printf (QSE_T("NORMAL REPLY 222222222222222222222 NORMAL REPLY\n")); qse_mbs_cat (proxy->res, buf) == (qse_size_t)-1 || qse_mbs_cat (proxy->res, QSE_MT("\r\n")) == (qse_size_t)-1) { - proxy->httpd->errnum = QSE_HTTPD_ENOMEM; + httpd->errnum = QSE_HTTPD_ENOMEM; return -1; } } @@ -531,14 +529,14 @@ qse_printf (QSE_T("NORMAL REPLY 222222222222222222222 NORMAL REPLY\n")); { if (qse_mbs_cat (proxy->res, QSE_MT("Transfer-Encoding: chunked\r\n")) == (qse_size_t)-1) { - proxy->httpd->errnum = QSE_HTTPD_ENOMEM; + 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) { - proxy->httpd->errnum = QSE_HTTPD_ENOMEM; + httpd->errnum = QSE_HTTPD_ENOMEM; return -1; } @@ -551,10 +549,10 @@ qse_printf (QSE_T("NORMAL REPLY 222222222222222222222 NORMAL REPLY\n")); if ((proxy->resflags & PROXY_RES_PEER_LENGTH) && proxy->peer_output_received > proxy->peer_output_length) { - if (proxy->httpd->opt.trait & QSE_HTTPD_LOGACT) + if (httpd->opt.trait & QSE_HTTPD_LOGACT) log_proxy_error (proxy, "proxy redundant output - "); - proxy->httpd->errnum = QSE_HTTPD_EINVAL; /* TODO: change it to a better error code */ + httpd->errnum = QSE_HTTPD_EINVAL; /* TODO: change it to a better error code */ return -1; } @@ -577,7 +575,7 @@ qse_printf (QSE_T("NORMAL REPLY 222222222222222222222 NORMAL REPLY\n")); qse_mbs_ncat (proxy->res, qse_htre_getcontentptr(res), qse_htre_getcontentlen(res)) == (qse_size_t)-1 || qse_mbs_cat (proxy->res, QSE_MT("\r\n")) == (qse_size_t)-1) { - proxy->httpd->errnum = QSE_HTTPD_ENOMEM; + httpd->errnum = QSE_HTTPD_ENOMEM; return -1; } } @@ -585,7 +583,7 @@ qse_printf (QSE_T("NORMAL REPLY 222222222222222222222 NORMAL REPLY\n")); { if (qse_mbs_ncat (proxy->res, qse_htre_getcontentptr(res), qse_htre_getcontentlen(res)) == (qse_size_t)-1) { - proxy->httpd->errnum = QSE_HTTPD_ENOMEM; + httpd->errnum = QSE_HTTPD_ENOMEM; return -1; } } @@ -596,9 +594,6 @@ qse_printf (QSE_T("NORMAL REPLY 222222222222222222222 NORMAL REPLY\n")); /* arrange to store further contents received to proxy->res */ qse_htre_setconcb (res, proxy_snatch_peer_output, xtn->task); } -#if 0 -qse_printf (QSE_T("NORMAL REPLY 222222222222222222222 NORMAL REPLY OK\n")); -#endif } proxy->res_pending = QSE_MBS_LEN(proxy->res) - proxy->res_consumed; @@ -909,7 +904,7 @@ oops: proxy->init_failed = 1; task->ctx = proxy; - proxy->httpd->errnum = QSE_HTTPD_ENOMEM; + httpd->errnum = QSE_HTTPD_ENOMEM; return 0; } @@ -960,7 +955,7 @@ qse_printf (QSE_T("task_main_proxy_5 trigger[0].mask=%d trigger[1].mask=%d trigg if (n <= -1) { /* can't return internal server error any more... */ - if (proxy->httpd->opt.trait & QSE_HTTPD_LOGACT) + if (httpd->opt.trait & QSE_HTTPD_LOGACT) log_proxy_error (proxy, "proxy send-to-client error - "); return -1; } @@ -1043,7 +1038,7 @@ qse_printf (QSE_T("task_main_proxy_4 trigger[0].mask=%d trigger[1].mask=%d trigg if (proxy->peer_output_received > proxy->peer_output_length) { /* proxy returning too much data... something is wrong in PROXY */ - if (proxy->httpd->opt.trait & QSE_HTTPD_LOGACT) + if (httpd->opt.trait & QSE_HTTPD_LOGACT) log_proxy_error (proxy, "proxy redundant output - "); return -1; } @@ -1065,7 +1060,7 @@ qse_printf (QSE_T("task_main_proxy_4 trigger[0].mask=%d trigger[1].mask=%d trigg if (n <= -1) { /* can't return internal server error any more... */ - if (proxy->httpd->opt.trait & QSE_HTTPD_LOGACT) + if (httpd->opt.trait & QSE_HTTPD_LOGACT) log_proxy_error (proxy, "proxy send-to-client error - "); return -1; } diff --git a/qse/lib/http/httpd-std.c b/qse/lib/http/httpd-std.c index 53361df9..fc45cc30 100644 --- a/qse/lib/http/httpd-std.c +++ b/qse/lib/http/httpd-std.c @@ -1906,7 +1906,11 @@ if (qse_htre_getcontentlen(req) > 0) /* 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 (rsrc.type == QSE_HTTPD_RSRC_ERR) + { +qse_printf (QSE_T("DISCARD 3\n")); + qse_httpd_discardcontent (httpd, req); + } } if (task == QSE_NULL) goto oops; } @@ -2414,7 +2418,7 @@ static int make_resource ( struct rsrc_tmp_t tmp; qse_httpd_stat_t st; - int n, stx, meth; + int n, stx, method; QSE_MEMSET (&tmp, 0, QSE_SIZEOF(tmp)); tmp.qpath = qse_htre_getqpath(req); @@ -2439,16 +2443,24 @@ static int make_resource ( } /* 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_) + method = qse_htre_getqmethodtype(req); + switch (method) { -/* TODO: handle more method types */ - /* method not allowed */ - target->type = QSE_HTTPD_RSRC_ERR; - target->u.err.code = 405; - return 0; + case QSE_HTTP_HEAD: + case QSE_HTTP_GET: + case QSE_HTTP_POST: + case QSE_HTTP_PUT: + case QSE_HTTP_DELETE: + case QSE_HTTP_OPTIONS: + /* let these methods be handled locally */ + break; + + default: + /* method not allowed */ + target->type = QSE_HTTPD_RSRC_ERR; + target->u.err.code = 405; + return 0; } #endif diff --git a/qse/lib/http/httpd-task.c b/qse/lib/http/httpd-task.c index cb928766..b116052d 100644 --- a/qse/lib/http/httpd-task.c +++ b/qse/lib/http/httpd-task.c @@ -263,6 +263,7 @@ qse_httpd_task_t* qse_httpd_entaskerr ( qse_httpd_t* httpd, qse_httpd_client_t* client, qse_httpd_task_t* pred, int code, qse_htre_t* req) { + qse_htre_discardcontent (req); return entask_status ( httpd, client, pred, code, QSE_NULL, qse_htre_getversion(req), (req->attr.flags & QSE_HTRE_ATTR_KEEPALIVE)); @@ -411,17 +412,14 @@ qse_httpd_task_t* qse_httpd_entaskrsrc ( break; case QSE_HTTPD_RSRC_DIR: - qse_httpd_discardcontent (httpd, req); task = qse_httpd_entaskdir (httpd, client, pred, rsrc->u.dir.path, req); break; case QSE_HTTPD_RSRC_ERR: - qse_httpd_discardcontent (httpd, req); task = qse_httpd_entaskerr (httpd, client, pred, rsrc->u.err.code, req); break; case QSE_HTTPD_RSRC_FILE: - qse_httpd_discardcontent (httpd, req); task = qse_httpd_entaskfile (httpd, client, pred, rsrc->u.file.path, rsrc->u.file.mime, req); break;