added mio_dupbcstrs() and mio_dupucstrs()
changed mio_svc_htts_start() to access the main processor callback
This commit is contained in:
parent
f373f367b3
commit
aa5c70c3f5
@ -748,6 +748,102 @@ static void on_dnc_resolve_brief (mio_svc_dnc_t* dnc, mio_dns_msg_t* reqmsg, mio
|
||||
}
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
int process_http_request (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* req)
|
||||
{
|
||||
mio_t* mio = mio_svc_htts_getmio(htts);
|
||||
// mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(csck);
|
||||
mio_http_method_t mth;
|
||||
|
||||
/* percent-decode the query path to the original buffer
|
||||
* since i'm not going to need it in the original form
|
||||
* any more. once it's decoded in the peek mode,
|
||||
* the decoded query path is made available in the
|
||||
* non-peek mode as well */
|
||||
|
||||
MIO_DEBUG2 (mio, "[RAW-REQ] %s %s\n", mio_htre_getqmethodname(req), mio_htre_getqpath(req));
|
||||
|
||||
mio_htre_perdecqpath(req);
|
||||
/* TODO: proper request logging */
|
||||
|
||||
MIO_DEBUG2 (mio, "[REQ] %s %s\n", mio_htre_getqmethodname(req), mio_htre_getqpath(req));
|
||||
|
||||
#if 0
|
||||
mio_printf (MIO_T("================================\n"));
|
||||
mio_printf (MIO_T("[%lu] %hs REQUEST ==> [%hs] version[%d.%d %hs] method[%hs]\n"),
|
||||
(unsigned long)time(NULL),
|
||||
(peek? MIO_MT("PEEK"): MIO_MT("HANDLE")),
|
||||
mio_htre_getqpath(req),
|
||||
mio_htre_getmajorversion(req),
|
||||
mio_htre_getminorversion(req),
|
||||
mio_htre_getverstr(req),
|
||||
mio_htre_getqmethodname(req)
|
||||
);
|
||||
if (mio_htre_getqparam(req))
|
||||
mio_printf (MIO_T("PARAMS ==> [%hs]\n"), mio_htre_getqparam(req));
|
||||
|
||||
mio_htb_walk (&req->hdrtab, walk, MIO_NULL);
|
||||
if (mio_htre_getcontentlen(req) > 0)
|
||||
{
|
||||
mio_printf (MIO_T("CONTENT [%.*S]\n"), (int)mio_htre_getcontentlen(req), mio_htre_getcontentptr(req));
|
||||
}
|
||||
#endif
|
||||
|
||||
mth = mio_htre_getqmethodtype(req);
|
||||
/* 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 0
|
||||
/* TODO support X-HTTP-Method-Override */
|
||||
if (data.method == MIO_HTTP_POST)
|
||||
{
|
||||
tmp = mio_htre_getheaderval(req, MIO_MT("X-HTTP-Method-Override"));
|
||||
if (tmp)
|
||||
{
|
||||
/*while (tmp->next) tmp = tmp->next;*/ /* get the last value */
|
||||
data.method = mio_mbstohttpmethod (tmp->ptr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
if (mth == MIO_HTTP_CONNECT)
|
||||
{
|
||||
/* CONNECT method must not have content set.
|
||||
* however, arrange to discard it if so.
|
||||
*
|
||||
* NOTE: CONNECT is implemented to ignore many headers like
|
||||
* 'Expect: 100-continue' and 'Connection: keep-alive'. */
|
||||
mio_htre_discardcontent (req);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* this part can be checked in actual mio_svc_htts_doXXX() functions.
|
||||
* some doXXX handlers may not require length for POST.
|
||||
* it may be able to simply accept till EOF? or treat as if CONTENT_LENGTH is 0*/
|
||||
if (mth == MIO_HTTP_POST && !(req->flags & (MIO_HTRE_ATTR_LENGTH | MIO_HTRE_ATTR_CHUNKED)))
|
||||
{
|
||||
/* POST without Content-Length nor not chunked */
|
||||
mio_htre_discardcontent (req);
|
||||
/* 411 Length Required - can't keep alive. Force disconnect */
|
||||
req->flags &= ~MIO_HTRE_ATTR_KEEPALIVE; /* to cause sendstatus() to close */
|
||||
if (mio_svc_htts_sendstatus(htts, csck, req, 411, MIO_NULL) <= -1) goto oops;
|
||||
}
|
||||
else
|
||||
|
||||
{
|
||||
#endif
|
||||
/*const mio_bch_t* qpath = mio_htre_getqpath(req);*/
|
||||
if (mio_svc_htts_docgi(htts, csck, req, "", mio_htre_getqpath(req)) <= -1) goto oops;
|
||||
|
||||
return 0;
|
||||
|
||||
oops:
|
||||
mio_dev_sck_halt (csck);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
static mio_t* g_mio;
|
||||
@ -976,7 +1072,7 @@ for (i = 0; i < 5; i++)
|
||||
mio_bcstrtoskad (mio, "127.0.0.1:9988", &htts_bind_addr);
|
||||
|
||||
dnc = mio_svc_dnc_start(mio, &servaddr, MIO_NULL, &send_tmout, &reply_tmout, 2); /* option - send to all, send one by one */
|
||||
htts = mio_svc_htts_start(mio, &htts_bind_addr);
|
||||
htts = mio_svc_htts_start(mio, &htts_bind_addr, process_http_request);
|
||||
mio_svc_htts_setservernamewithbcstr (htts, "MIO-HTTP");
|
||||
|
||||
#if 1
|
||||
|
@ -1217,43 +1217,9 @@ int mio_htrd_feed (mio_htrd_t* htrd, const mio_bch_t* req, mio_oow_t len, mio_oo
|
||||
/* need to clear request on error?
|
||||
clear_feed (htrd); */
|
||||
return -1;
|
||||
/// TODO: PEEKONLY doens't seem to be neede. delete it...
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (htrd->option & MIO_HTRD_PEEKONLY)
|
||||
{
|
||||
/* when MIO_HTRD_PEEKONLY is set,
|
||||
* the peek callback is invoked once
|
||||
* a complete header is seen. the caller
|
||||
* should not feed more data by calling
|
||||
* this function again once the callback is
|
||||
* invoked. the trailing data is appended
|
||||
* to the content buffer.
|
||||
*
|
||||
* NOTE: if the current feed that completed
|
||||
* the header contains the next request,
|
||||
* the next request is treated as if it
|
||||
* belongs to the current request.
|
||||
*
|
||||
* In priciple, this option was added for
|
||||
* reading CGI outputs. So it comes with
|
||||
* awkwardity described above.
|
||||
*/
|
||||
if (ptr < end && push_content(htrd, ptr, end - ptr) <= -1) return -1;
|
||||
|
||||
/* i don't really know if it is really completed
|
||||
* with content. MIO_HTRD_PEEKONLY is not compatible
|
||||
* with the completed state. anyway, let me complete
|
||||
* it. */
|
||||
mio_htre_completecontent (&htrd->re);
|
||||
|
||||
/* this jump is only to invoke the peek
|
||||
* callback. this function should not be fed
|
||||
* more. */
|
||||
goto feedme_more;
|
||||
}
|
||||
|
||||
/* carry on processing content body fed together with the header */
|
||||
if (htrd->re.flags & MIO_HTRE_ATTR_CHUNKED)
|
||||
{
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "mio-pro.h" /* for cgi */
|
||||
#include "mio-fmt.h"
|
||||
#include "mio-chr.h"
|
||||
#include "mio-path.h"
|
||||
#include "mio-prv.h"
|
||||
|
||||
|
||||
@ -35,6 +36,8 @@ struct mio_svc_htts_t
|
||||
{
|
||||
MIO_SVC_HEADER;
|
||||
|
||||
mio_svc_htts_proc_req_t proc_req;
|
||||
|
||||
mio_dev_sck_t* lsck;
|
||||
mio_svc_htts_cli_t cli; /* list head for client list */
|
||||
|
||||
@ -98,110 +101,11 @@ static int test_func_handler (int rfd, int wfd)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int process_request (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* req)
|
||||
{
|
||||
//server_xtn_t* server_xtn = GET_SERVER_XTN(htts, client->server);
|
||||
//mio_htts_task_t* task;
|
||||
mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(csck);
|
||||
mio_http_method_t mth;
|
||||
//mio_htts_rsrc_t rsrc;
|
||||
|
||||
/* percent-decode the query path to the original buffer
|
||||
* since i'm not going to need it in the original form
|
||||
* any more. once it's decoded in the peek mode,
|
||||
* the decoded query path is made available in the
|
||||
* non-peek mode as well */
|
||||
|
||||
MIO_DEBUG2 (htts->mio, "[RAW-REQ] %s %s\n", mio_htre_getqmethodname(req), mio_htre_getqpath(req));
|
||||
|
||||
mio_htre_perdecqpath(req);
|
||||
/* TODO: proper request logging */
|
||||
|
||||
MIO_DEBUG2 (htts->mio, "[REQ] %s %s\n", mio_htre_getqmethodname(req), mio_htre_getqpath(req));
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
mio_printf (MIO_T("================================\n"));
|
||||
mio_printf (MIO_T("[%lu] %hs REQUEST ==> [%hs] version[%d.%d %hs] method[%hs]\n"),
|
||||
(unsigned long)time(NULL),
|
||||
(peek? MIO_MT("PEEK"): MIO_MT("HANDLE")),
|
||||
mio_htre_getqpath(req),
|
||||
mio_htre_getmajorversion(req),
|
||||
mio_htre_getminorversion(req),
|
||||
mio_htre_getverstr(req),
|
||||
mio_htre_getqmethodname(req)
|
||||
);
|
||||
if (mio_htre_getqparam(req))
|
||||
mio_printf (MIO_T("PARAMS ==> [%hs]\n"), mio_htre_getqparam(req));
|
||||
|
||||
mio_htb_walk (&req->hdrtab, walk, MIO_NULL);
|
||||
if (mio_htre_getcontentlen(req) > 0)
|
||||
{
|
||||
mio_printf (MIO_T("CONTENT [%.*S]\n"), (int)mio_htre_getcontentlen(req), mio_htre_getcontentptr(req));
|
||||
}
|
||||
#endif
|
||||
|
||||
mth = mio_htre_getqmethodtype(req);
|
||||
/* 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 0
|
||||
/* TODO support X-HTTP-Method-Override */
|
||||
if (data.method == MIO_HTTP_POST)
|
||||
{
|
||||
tmp = mio_htre_getheaderval(req, MIO_MT("X-HTTP-Method-Override"));
|
||||
if (tmp)
|
||||
{
|
||||
/*while (tmp->next) tmp = tmp->next;*/ /* get the last value */
|
||||
data.method = mio_mbstohttpmethod (tmp->ptr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
if (mth == MIO_HTTP_CONNECT)
|
||||
{
|
||||
/* CONNECT method must not have content set.
|
||||
* however, arrange to discard it if so.
|
||||
*
|
||||
* NOTE: CONNECT is implemented to ignore many headers like
|
||||
* 'Expect: 100-continue' and 'Connection: keep-alive'. */
|
||||
mio_htre_discardcontent (req);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* this part can be checked in actual mio_svc_htts_doXXX() functions.
|
||||
* some doXXX handlers may not require length for POST.
|
||||
* it may be able to simply accept till EOF? or treat as if CONTENT_LENGTH is 0*/
|
||||
if (mth == MIO_HTTP_POST && !(req->flags & (MIO_HTRE_ATTR_LENGTH | MIO_HTRE_ATTR_CHUNKED)))
|
||||
{
|
||||
/* POST without Content-Length nor not chunked */
|
||||
mio_htre_discardcontent (req);
|
||||
/* 411 Length Required - can't keep alive. Force disconnect */
|
||||
req->flags &= ~MIO_HTRE_ATTR_KEEPALIVE; /* to cause sendstatus() to close */
|
||||
if (mio_svc_htts_sendstatus(htts, csck, req, 411, MIO_NULL) <= -1) goto oops;
|
||||
}
|
||||
else
|
||||
|
||||
{
|
||||
#endif
|
||||
/*const mio_bch_t* qpath = mio_htre_getqpath(req);*/
|
||||
if (mio_svc_htts_docgi(htts, csck, req, "") <= -1) goto oops;
|
||||
|
||||
return 0;
|
||||
|
||||
oops:
|
||||
mio_dev_sck_halt (csck);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int client_htrd_peek_request (mio_htrd_t* htrd, mio_htre_t* req)
|
||||
{
|
||||
htrd_xtn_t* htrdxtn = (htrd_xtn_t*)mio_htrd_getxtn(htrd);
|
||||
mio_svc_htts_cli_t* sckxtn = (mio_svc_htts_cli_t*)mio_dev_sck_getxtn(htrdxtn->sck);
|
||||
return process_request(sckxtn->htts, htrdxtn->sck, req);
|
||||
return sckxtn->htts->proc_req(sckxtn->htts, htrdxtn->sck, req);
|
||||
}
|
||||
|
||||
|
||||
@ -439,7 +343,7 @@ static void listener_on_disconnect (mio_dev_sck_t* sck)
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
mio_svc_htts_t* mio_svc_htts_start (mio_t* mio, const mio_skad_t* bind_addr)
|
||||
mio_svc_htts_t* mio_svc_htts_start (mio_t* mio, const mio_skad_t* bind_addr, mio_svc_htts_proc_req_t proc_req)
|
||||
{
|
||||
mio_svc_htts_t* htts = MIO_NULL;
|
||||
union
|
||||
@ -455,6 +359,7 @@ mio_svc_htts_t* mio_svc_htts_start (mio_t* mio, const mio_skad_t* bind_addr)
|
||||
|
||||
htts->mio = mio;
|
||||
htts->svc_stop = mio_svc_htts_stop;
|
||||
htts->proc_req = proc_req;
|
||||
|
||||
MIO_MEMSET (&info, 0, MIO_SIZEOF(info));
|
||||
switch (mio_skad_family(bind_addr))
|
||||
@ -1314,6 +1219,8 @@ struct cgi_peer_fork_ctx_t
|
||||
mio_svc_htts_cli_t* cli;
|
||||
mio_htre_t* req;
|
||||
const mio_bch_t* docroot;
|
||||
const mio_bch_t* script;
|
||||
mio_bch_t* actual_script;
|
||||
};
|
||||
typedef struct cgi_peer_fork_ctx_t cgi_peer_fork_ctx_t;
|
||||
|
||||
@ -1362,24 +1269,27 @@ static int cgi_peer_on_fork (mio_dev_pro_t* pro, void* fork_ctx)
|
||||
cgi_peer_fork_ctx_t* fc = (cgi_peer_fork_ctx_t*)fork_ctx;
|
||||
mio_oow_t content_length;
|
||||
const mio_bch_t* qparam;
|
||||
const char* path;
|
||||
const char* path, * lang;
|
||||
mio_bch_t tmp[256];
|
||||
mio_becs_t dbuf;
|
||||
|
||||
qparam = mio_htre_getqparam(fc->req);
|
||||
|
||||
path = getenv("PATH");
|
||||
lang = getenv("LANG");
|
||||
clearenv ();
|
||||
if (path) setenv ("PATH", path, 1);
|
||||
if (lang) setenv ("LANG", lang, 1);
|
||||
|
||||
setenv ("GATEWAY_INTERFACE", "CGI/1.1", 1);
|
||||
|
||||
mio_fmttobcstr (pro->mio, tmp, MIO_COUNTOF(tmp), "HTTP/%d.%d", (int)mio_htre_getmajorversion(fc->req), (int)mio_htre_getminorversion(fc->req));
|
||||
setenv ("SERVER_PROTOCOL", tmp, 1);
|
||||
|
||||
//setenv ("SCRIPT_FILENAME",
|
||||
//setenv ("SCRIPT_NAME",
|
||||
setenv ("DOCUMENT_ROOT", fc->docroot, 1);
|
||||
setenv ("SCRIPT_NAME", fc->script, 1);
|
||||
setenv ("SCRIPT_FILENAME", fc->actual_script, 1);
|
||||
/* TODO: PATH_INFO */
|
||||
|
||||
setenv ("REQUEST_METHOD", mio_htre_getqmethodname(fc->req), 1);
|
||||
setenv ("REQUEST_URI", mio_htre_getqpath(fc->req), 1);
|
||||
@ -1422,8 +1332,7 @@ static int cgi_peer_on_fork (mio_dev_pro_t* pro, void* fork_ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int mio_svc_htts_docgi (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* req, const mio_bch_t* docroot)
|
||||
int mio_svc_htts_docgi (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* req, const mio_bch_t* docroot, const mio_bch_t* script)
|
||||
{
|
||||
mio_t* mio = htts->mio;
|
||||
mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(csck);
|
||||
@ -1439,10 +1348,13 @@ int mio_svc_htts_docgi (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* r
|
||||
fc.cli = cli;
|
||||
fc.req = req;
|
||||
fc.docroot = docroot;
|
||||
fc.script = script;
|
||||
fc.actual_script = mio_svc_htts_dupmergepaths(htts, docroot, script);
|
||||
if (!fc.actual_script) goto oops;
|
||||
|
||||
MIO_MEMSET (&mi, 0, MIO_SIZEOF(mi));
|
||||
mi.flags = MIO_DEV_PRO_READOUT | MIO_DEV_PRO_ERRTONUL | MIO_DEV_PRO_WRITEIN /*| MIO_DEV_PRO_FORGET_CHILD*/;
|
||||
mi.cmd = mio_htre_getqpath(req); /* TODO: combine it with docroot */
|
||||
mi.cmd = fc.actual_script;
|
||||
mi.on_read = cgi_peer_on_read;
|
||||
mi.on_write = cgi_peer_on_write;
|
||||
mi.on_close = cgi_peer_on_close;
|
||||
@ -1468,10 +1380,6 @@ int mio_svc_htts_docgi (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* r
|
||||
MIO_ASSERT (mio, cli->rsrc == MIO_NULL);
|
||||
MIO_SVC_HTTS_RSRC_ATTACH (cgi_state, cli->rsrc);
|
||||
|
||||
/* TODO: create cgi environment variables... */
|
||||
/* TODO:
|
||||
* never put Expect: 100-continue to environment variable
|
||||
*/
|
||||
if (access(mi.cmd, X_OK) == -1)
|
||||
{
|
||||
cgi_state_send_final_status_to_client (cgi_state, 403); /* 403 Forbidden */
|
||||
@ -1588,17 +1496,29 @@ int mio_svc_htts_docgi (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* r
|
||||
|
||||
/* TODO: store current input watching state and use it when destroying the cgi_state data */
|
||||
if (mio_dev_sck_read(csck, !(cgi_state->over & CGI_STATE_OVER_READ_FROM_CLIENT)) <= -1) goto oops;
|
||||
mio_freemem (mio, fc.actual_script);
|
||||
return 0;
|
||||
|
||||
oops:
|
||||
MIO_DEBUG2 (mio, "HTTS(%p) - FAILURE in docgi - socket(%p)\n", htts, csck);
|
||||
if (cgi_state) cgi_state_halt_participating_devices (cgi_state);
|
||||
if (fc.actual_script) mio_freemem (mio, fc.actual_script);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
int mio_svc_htts_dofile (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* req, const mio_bch_t* docroot)
|
||||
#if 0
|
||||
int mio_svc_htts_dothrfunc (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* req, mio_svc_htts_func_t func)
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
int mio_svc_htts_dofile (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* req, const mio_bch_t* docroot, const mio_bch_t* file)
|
||||
{
|
||||
switch (mio_htre_getqmethodtype(req))
|
||||
{
|
||||
@ -1668,6 +1588,26 @@ void mio_svc_htts_fmtgmtime (mio_svc_htts_t* htts, const mio_ntime_t* nt, mio_bc
|
||||
mio_fmt_http_time_to_bcstr(nt, buf, len);
|
||||
}
|
||||
|
||||
mio_bch_t* mio_svc_htts_dupmergepaths (mio_svc_htts_t* htts, const mio_bch_t* base, const mio_bch_t* path)
|
||||
{
|
||||
mio_bch_t* xpath;
|
||||
const mio_bch_t* ta[4];
|
||||
mio_oow_t idx = 0;
|
||||
|
||||
ta[idx++] = base;
|
||||
if (path[0] != '\0')
|
||||
{
|
||||
ta[idx++] = "/";
|
||||
ta[idx++] = path;
|
||||
}
|
||||
ta[idx++] = MIO_NULL;
|
||||
xpath = mio_dupbcstrs(htts->mio, ta, MIO_NULL);
|
||||
if (MIO_UNLIKELY(!xpath)) return MIO_NULL;
|
||||
|
||||
mio_canon_bcstr_path (xpath, xpath, 0);
|
||||
return xpath;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
#if 0
|
||||
|
@ -387,15 +387,7 @@ typedef void (*mio_svc_dnc_on_resolve_t) (
|
||||
mio_oow_t len
|
||||
);
|
||||
|
||||
#if defined(MIO_HAVE_INLINE)
|
||||
static MIO_INLINE mio_t* mio_svc_dns_getmio(mio_svc_dns_t* svc) { return mio_svc_getmio((mio_svc_t*)svc); }
|
||||
static MIO_INLINE mio_t* mio_svc_dnc_getmio(mio_svc_dnc_t* svc) { return mio_svc_getmio((mio_svc_t*)svc); }
|
||||
static MIO_INLINE mio_t* mio_svc_dnr_getmio(mio_svc_dnr_t* svc) { return mio_svc_getmio((mio_svc_t*)svc); }
|
||||
#else
|
||||
# define mio_svc_dns_getmio(svc) mio_svc_getmio(svc)
|
||||
# define mio_svc_dnc_getmio(svc) mio_svc_getmio(svc)
|
||||
# define mio_svc_dnr_getmio(svc) mio_svc_getmio(svc)
|
||||
#endif
|
||||
|
||||
|
||||
enum mio_svc_dnc_send_flag_t
|
||||
{
|
||||
@ -476,6 +468,16 @@ MIO_EXPORT void mio_svc_dnc_stop (
|
||||
mio_svc_dnc_t* dnc
|
||||
);
|
||||
|
||||
#if defined(MIO_HAVE_INLINE)
|
||||
static MIO_INLINE mio_t* mio_svc_dns_getmio(mio_svc_dns_t* svc) { return mio_svc_getmio((mio_svc_t*)svc); }
|
||||
static MIO_INLINE mio_t* mio_svc_dnc_getmio(mio_svc_dnc_t* svc) { return mio_svc_getmio((mio_svc_t*)svc); }
|
||||
static MIO_INLINE mio_t* mio_svc_dnr_getmio(mio_svc_dnr_t* svc) { return mio_svc_getmio((mio_svc_t*)svc); }
|
||||
#else
|
||||
# define mio_svc_dns_getmio(svc) mio_svc_getmio(svc)
|
||||
# define mio_svc_dnc_getmio(svc) mio_svc_getmio(svc)
|
||||
# define mio_svc_dnr_getmio(svc) mio_svc_getmio(svc)
|
||||
#endif
|
||||
|
||||
MIO_EXPORT mio_dns_msg_t* mio_svc_dnc_sendmsg (
|
||||
mio_svc_dnc_t* dnc,
|
||||
mio_dns_bhdr_t* bdns,
|
||||
|
@ -55,11 +55,10 @@ enum mio_htrd_option_t
|
||||
MIO_HTRD_SKIPEMPTYLINES = (1 << 0), /**< skip leading empty lines before the initial line */
|
||||
MIO_HTRD_SKIPINITIALLINE = (1 << 1), /**< skip processing an initial line */
|
||||
MIO_HTRD_CANONQPATH = (1 << 2), /**< canonicalize the query path */
|
||||
MIO_HTRD_PEEKONLY = (1 << 3), /**< trigger a peek callback after headers without processing contents */
|
||||
MIO_HTRD_REQUEST = (1 << 4), /**< parse input as a request */
|
||||
MIO_HTRD_RESPONSE = (1 << 5), /**< parse input as a response */
|
||||
MIO_HTRD_TRAILERS = (1 << 6), /**< store trailers in a separate table */
|
||||
MIO_HTRD_STRICT = (1 << 7) /**< be more picky */
|
||||
MIO_HTRD_REQUEST = (1 << 3), /**< parse input as a request */
|
||||
MIO_HTRD_RESPONSE = (1 << 4), /**< parse input as a response */
|
||||
MIO_HTRD_TRAILERS = (1 << 5), /**< store trailers in a separate table */
|
||||
MIO_HTRD_STRICT = (1 << 6) /**< be more picky */
|
||||
};
|
||||
|
||||
typedef enum mio_htrd_option_t mio_htrd_option_t;
|
||||
|
@ -27,8 +27,74 @@
|
||||
#ifndef _MIO_HTRE_H_
|
||||
#define _MIO_HTRE_H_
|
||||
|
||||
#include <mio-http.h>
|
||||
#include <mio-htb.h>
|
||||
#include <mio-ecs.h>
|
||||
|
||||
/**
|
||||
* The mio_http_version_t type defines http version.
|
||||
*/
|
||||
struct mio_http_version_t
|
||||
{
|
||||
short major; /**< major version */
|
||||
short minor; /**< minor version */
|
||||
};
|
||||
|
||||
typedef struct mio_http_version_t mio_http_version_t;
|
||||
|
||||
/**
|
||||
* The mio_http_method_t type defines http methods .
|
||||
*/
|
||||
enum mio_http_method_t
|
||||
{
|
||||
MIO_HTTP_OTHER,
|
||||
|
||||
/* rfc 2616 */
|
||||
MIO_HTTP_HEAD,
|
||||
MIO_HTTP_GET,
|
||||
MIO_HTTP_POST,
|
||||
MIO_HTTP_PUT,
|
||||
MIO_HTTP_DELETE,
|
||||
MIO_HTTP_OPTIONS,
|
||||
MIO_HTTP_TRACE,
|
||||
MIO_HTTP_CONNECT
|
||||
|
||||
#if 0
|
||||
/* rfc 2518 */
|
||||
MIO_HTTP_PROPFIND,
|
||||
MIO_HTTP_PROPPATCH,
|
||||
MIO_HTTP_MKCOL,
|
||||
MIO_HTTP_COPY,
|
||||
MIO_HTTP_MOVE,
|
||||
MIO_HTTP_LOCK,
|
||||
MIO_HTTP_UNLOCK,
|
||||
|
||||
/* rfc 3253 */
|
||||
MIO_HTTP_VERSION_CONTROL,
|
||||
MIO_HTTP_REPORT,
|
||||
MIO_HTTP_CHECKOUT,
|
||||
MIO_HTTP_CHECKIN,
|
||||
MIO_HTTP_UNCHECKOUT,
|
||||
MIO_HTTP_MKWORKSPACE,
|
||||
MIO_HTTP_UPDATE,
|
||||
MIO_HTTP_LABEL,
|
||||
MIO_HTTP_MERGE,
|
||||
MIO_HTTP_BASELINE_CONTROL,
|
||||
MIO_HTTP_MKACTIVITY,
|
||||
|
||||
/* microsoft */
|
||||
MIO_HTTP_BPROPFIND,
|
||||
MIO_HTTP_BPROPPATCH,
|
||||
MIO_HTTP_BCOPY,
|
||||
MIO_HTTP_BDELETE,
|
||||
MIO_HTTP_BMOVE,
|
||||
MIO_HTTP_NOTIFY,
|
||||
MIO_HTTP_POLL,
|
||||
MIO_HTTP_SUBSCRIBE,
|
||||
MIO_HTTP_UNSUBSCRIBE,
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef enum mio_http_method_t mio_http_method_t;
|
||||
|
||||
/*
|
||||
* You should not manipulate an object of the #mio_htre_t
|
||||
@ -37,7 +103,7 @@
|
||||
*/
|
||||
|
||||
/* header and contents of request/response */
|
||||
/*typedef struct mio_htre_t mio_htre_t; <--- defined in mio-http.h TODO: remove recursive definition */
|
||||
typedef struct mio_htre_t mio_htre_t;
|
||||
typedef struct mio_htre_hdrval_t mio_htre_hdrval_t;
|
||||
|
||||
enum mio_htre_state_t
|
||||
|
@ -27,77 +27,12 @@
|
||||
|
||||
#include <mio-ecs.h>
|
||||
#include <mio-sck.h>
|
||||
#include <mio-htre.h>
|
||||
|
||||
/** \file
|
||||
* This file provides basic data types and functions for the http protocol.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The mio_http_version_t type defines http version.
|
||||
*/
|
||||
struct mio_http_version_t
|
||||
{
|
||||
short major; /**< major version */
|
||||
short minor; /**< minor version */
|
||||
};
|
||||
|
||||
typedef struct mio_http_version_t mio_http_version_t;
|
||||
|
||||
/**
|
||||
* The mio_http_method_t type defines http methods .
|
||||
*/
|
||||
enum mio_http_method_t
|
||||
{
|
||||
MIO_HTTP_OTHER,
|
||||
|
||||
/* rfc 2616 */
|
||||
MIO_HTTP_HEAD,
|
||||
MIO_HTTP_GET,
|
||||
MIO_HTTP_POST,
|
||||
MIO_HTTP_PUT,
|
||||
MIO_HTTP_DELETE,
|
||||
MIO_HTTP_OPTIONS,
|
||||
MIO_HTTP_TRACE,
|
||||
MIO_HTTP_CONNECT
|
||||
|
||||
#if 0
|
||||
/* rfc 2518 */
|
||||
MIO_HTTP_PROPFIND,
|
||||
MIO_HTTP_PROPPATCH,
|
||||
MIO_HTTP_MKCOL,
|
||||
MIO_HTTP_COPY,
|
||||
MIO_HTTP_MOVE,
|
||||
MIO_HTTP_LOCK,
|
||||
MIO_HTTP_UNLOCK,
|
||||
|
||||
/* rfc 3253 */
|
||||
MIO_HTTP_VERSION_CONTROL,
|
||||
MIO_HTTP_REPORT,
|
||||
MIO_HTTP_CHECKOUT,
|
||||
MIO_HTTP_CHECKIN,
|
||||
MIO_HTTP_UNCHECKOUT,
|
||||
MIO_HTTP_MKWORKSPACE,
|
||||
MIO_HTTP_UPDATE,
|
||||
MIO_HTTP_LABEL,
|
||||
MIO_HTTP_MERGE,
|
||||
MIO_HTTP_BASELINE_CONTROL,
|
||||
MIO_HTTP_MKACTIVITY,
|
||||
|
||||
/* microsoft */
|
||||
MIO_HTTP_BPROPFIND,
|
||||
MIO_HTTP_BPROPPATCH,
|
||||
MIO_HTTP_BCOPY,
|
||||
MIO_HTTP_BDELETE,
|
||||
MIO_HTTP_BMOVE,
|
||||
MIO_HTTP_NOTIFY,
|
||||
MIO_HTTP_POLL,
|
||||
MIO_HTTP_SUBSCRIBE,
|
||||
MIO_HTTP_UNSUBSCRIBE,
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef enum mio_http_method_t mio_http_method_t;
|
||||
|
||||
/**
|
||||
* The #mio_http_range_int_t type defines an integer that can represent
|
||||
* a range offset. Depening on the size of #mio_foff_t, it is defined to
|
||||
@ -155,7 +90,6 @@ typedef enum mio_perenc_http_opt_t mio_perenc_bcstr_opt_t;
|
||||
|
||||
|
||||
/* -------------------------------------------------------------- */
|
||||
typedef struct mio_htre_t mio_htre_t;
|
||||
typedef struct mio_svc_htts_t mio_svc_htts_t;
|
||||
typedef struct mio_svc_httc_t mio_svc_httc_t;
|
||||
|
||||
@ -180,6 +114,14 @@ struct mio_svc_htts_rsrc_t
|
||||
|
||||
#define MIO_SVC_HTTS_RSRC_ATTACH(rsrc, var) do { (var) = (rsrc); ++(rsrc)->rsrc_refcnt; } while(0)
|
||||
#define MIO_SVC_HTTS_RSRC_DETACH(rsrc_var) do { if (--(rsrc_var)->rsrc_refcnt == 0) { mio_svc_htts_rsrc_t* __rsrc_tmp = (rsrc_var); (rsrc_var) = MIO_NULL; mio_svc_htts_rsrc_kill(__rsrc_tmp); } else { (rsrc_var) = MIO_NULL; } } while(0)
|
||||
|
||||
|
||||
typedef int (*mio_svc_htts_proc_req_t) (
|
||||
mio_svc_htts_t* htts,
|
||||
mio_dev_sck_t* sck,
|
||||
mio_htre_t* req
|
||||
);
|
||||
|
||||
/* -------------------------------------------------------------- */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
@ -280,13 +222,20 @@ MIO_EXPORT mio_bch_t* mio_perenc_http_bcstrdup (
|
||||
|
||||
MIO_EXPORT mio_svc_htts_t* mio_svc_htts_start (
|
||||
mio_t* mio,
|
||||
const mio_skad_t* bind_addr
|
||||
const mio_skad_t* bind_addr,
|
||||
mio_svc_htts_proc_req_t proc_req
|
||||
);
|
||||
|
||||
MIO_EXPORT void mio_svc_htts_stop (
|
||||
mio_svc_htts_t* htts
|
||||
);
|
||||
|
||||
#if defined(MIO_HAVE_INLINE)
|
||||
static MIO_INLINE mio_t* mio_svc_htts_getmio(mio_svc_htts_t* svc) { return mio_svc_getmio((mio_svc_t*)svc); }
|
||||
#else
|
||||
# define mio_svc_htts_getmio(svc) mio_svc_getmio(svc)
|
||||
#endif
|
||||
|
||||
MIO_EXPORT int mio_svc_htts_setservernamewithbcstr (
|
||||
mio_svc_htts_t* htts,
|
||||
const mio_bch_t* server_name
|
||||
@ -296,25 +245,8 @@ MIO_EXPORT int mio_svc_htts_docgi (
|
||||
mio_svc_htts_t* htts,
|
||||
mio_dev_sck_t* csck,
|
||||
mio_htre_t* req,
|
||||
const mio_bch_t* docroot
|
||||
);
|
||||
|
||||
|
||||
MIO_EXPORT int mio_svc_htts_sendfile (
|
||||
mio_svc_htts_t* htts,
|
||||
mio_dev_sck_t* csck,
|
||||
const mio_bch_t* file_path,
|
||||
int status_code,
|
||||
mio_http_method_t method,
|
||||
const mio_http_version_t* version,
|
||||
int keepalive
|
||||
);
|
||||
|
||||
MIO_EXPORT void mio_svc_htts_fmtgmtime (
|
||||
mio_svc_htts_t* htts,
|
||||
const mio_ntime_t* nt,
|
||||
mio_bch_t* buf,
|
||||
mio_oow_t len
|
||||
const mio_bch_t* docroot,
|
||||
const mio_bch_t* script
|
||||
);
|
||||
|
||||
MIO_EXPORT mio_svc_htts_rsrc_t* mio_svc_htts_rsrc_make (
|
||||
@ -335,6 +267,12 @@ MIO_EXPORT void mio_svc_htts_fmtgmtime (
|
||||
mio_oow_t len
|
||||
);
|
||||
|
||||
MIO_EXPORT mio_bch_t* mio_svc_htts_dupmergepaths (
|
||||
mio_svc_htts_t* htts,
|
||||
const mio_bch_t* base,
|
||||
const mio_bch_t* path
|
||||
);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
@ -1776,7 +1776,6 @@ static int fmt_put_bchars_to_bch_buf (mio_fmtout_t* fmtout, const mio_bch_t* ptr
|
||||
return 1; /* success */
|
||||
}
|
||||
|
||||
|
||||
static int fmt_put_uchars_to_bch_buf (mio_fmtout_t* fmtout, const mio_uch_t* ptr, mio_oow_t len)
|
||||
{
|
||||
fmt_bch_buf_t* b = (fmt_bch_buf_t*)fmtout->ctx;
|
||||
|
@ -1113,6 +1113,18 @@ MIO_EXPORT mio_bch_t* mio_dupbcstr (
|
||||
mio_oow_t* bcslen /* [OUT] length */
|
||||
);
|
||||
|
||||
MIO_EXPORT mio_uch_t* mio_dupucstrs (
|
||||
mio_t* mio,
|
||||
const mio_uch_t* ucs[],
|
||||
mio_oow_t* ucslen
|
||||
);
|
||||
|
||||
MIO_EXPORT mio_bch_t* mio_dupbcstrs (
|
||||
mio_t* mio,
|
||||
const mio_bch_t* bcs[],
|
||||
mio_oow_t* bcslen
|
||||
);
|
||||
|
||||
#if defined(MIO_OOCH_IS_UCH)
|
||||
# define mio_dupoochars(mio,oocs,oocslen) mio_dupuchars(mio,oocs,oocslen)
|
||||
# define mio_dupoocstr(mio,oocs,oocslen) mio_dupucstr(mio,oocs,oocslen)
|
||||
|
@ -1729,5 +1729,39 @@ mio_bch_t* mio_dupbcstr (mio_t* mio, const mio_bch_t* bcs, mio_oow_t* bcslen)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
mio_uch_t* mio_dupucstrs (mio_t* mio, const mio_uch_t* ucs[], mio_oow_t* ucslen)
|
||||
{
|
||||
mio_uch_t* ptr;
|
||||
mio_oow_t len, i;
|
||||
|
||||
for (i = 0, len = 0; ucs[i]; i++) len += mio_count_ucstr(ucs[i]);
|
||||
|
||||
ptr = (mio_uch_t*)mio_allocmem(mio, (len + 1) * MIO_SIZEOF(mio_uch_t));
|
||||
if (!ptr) return MIO_NULL;
|
||||
|
||||
for (i = 0, len = 0; ucs[i]; i++)
|
||||
len += mio_copy_ucstr_unlimited(&ptr[len], ucs[i]);
|
||||
ptr[len] = '\0';
|
||||
|
||||
if (ucslen) *ucslen = len;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
mio_bch_t* mio_dupbcstrs (mio_t* mio, const mio_bch_t* bcs[], mio_oow_t* bcslen)
|
||||
{
|
||||
mio_bch_t* ptr;
|
||||
mio_oow_t len, i;
|
||||
|
||||
for (i = 0, len = 0; bcs[i]; i++) len += mio_count_bcstr(bcs[i]);
|
||||
|
||||
ptr = (mio_bch_t*)mio_allocmem(mio, (len + 1) * MIO_SIZEOF(mio_bch_t));
|
||||
if (!ptr) return MIO_NULL;
|
||||
|
||||
for (i = 0, len = 0; bcs[i]; i++)
|
||||
len += mio_copy_bcstr_unlimited(&ptr[len], bcs[i]);
|
||||
ptr[len] = '\0';
|
||||
|
||||
if (bcslen) *bcslen = len;
|
||||
return ptr;
|
||||
}
|
||||
/* ========================================================================= */
|
||||
|
Loading…
Reference in New Issue
Block a user