in the midst of debugging http server code

This commit is contained in:
hyung-hwan 2020-05-20 10:25:12 +00:00
parent 914dd35b37
commit d95bc9bc92
11 changed files with 253 additions and 128 deletions

View File

@ -377,7 +377,7 @@ static mio_bch_t* parse_initial_line (mio_htrd_t* htrd, mio_bch_t* line)
#else #else
while (*p != '\0' && !is_space_octet(*p)) while (*p != '\0' && !is_space_octet(*p))
{ {
if (*p == '?' && param.ptr == MIO_NULL) if (*p == '?' && !param.ptr)
{ {
tmp.len = p - tmp.ptr; /* length of the path part */ tmp.len = p - tmp.ptr; /* length of the path part */
*p++ = '\0'; /* null-terminate the path part */ *p++ = '\0'; /* null-terminate the path part */
@ -388,7 +388,15 @@ static mio_bch_t* parse_initial_line (mio_htrd_t* htrd, mio_bch_t* line)
/* the url must be followed by a space */ /* the url must be followed by a space */
if (!is_space_octet(*p)) goto badre; if (!is_space_octet(*p)) goto badre;
param.len = p - param.ptr; /* length of the param part */ if (param.ptr)
{
param.len = p - param.ptr; /* length of the param part */
}
else
{
tmp.len = p - tmp.ptr;
param.len = 0;
}
*p = '\0'; /* null-terminate the path or param part */ *p = '\0'; /* null-terminate the path or param part */
if (param.ptr) if (param.ptr)

View File

@ -9,6 +9,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <pthread.h> #include <pthread.h>
#include <stdlib.h> /* setenv */
#define CGI_ALLOW_UNLIMITED_REQ_CONTENT_LENGTH #define CGI_ALLOW_UNLIMITED_REQ_CONTENT_LENGTH
@ -113,6 +114,8 @@ static int process_request (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_
* 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 */
MIO_DEBUG2 (htts->mio, "[RAW-REQ] %s %s\n", mio_htre_getqmethodname(req), mio_htre_getqpath(req));
mio_htre_perdecqpath(req); mio_htre_perdecqpath(req);
/* TODO: proper request logging */ /* TODO: proper request logging */
@ -180,7 +183,7 @@ if (mio_htre_getcontentlen(req) > 0)
mio_htre_discardcontent (req); mio_htre_discardcontent (req);
/* 411 Length Required - can't keep alive. Force disconnect */ /* 411 Length Required - can't keep alive. Force disconnect */
req->flags &= ~MIO_HTRE_ATTR_KEEPALIVE; /* to cause sendstatus() to close */ req->flags &= ~MIO_HTRE_ATTR_KEEPALIVE; /* to cause sendstatus() to close */
if (mio_svc_htts_sendstatus(htts, csck, req, 411, MIO_NULL) <= -1) mio_dev_sck_halt (csck); /*TODO: redo this sendstatus */ if (mio_svc_htts_sendstatus(htts, csck, req, 411, MIO_NULL) <= -1) goto oops;
} }
else else
@ -189,35 +192,6 @@ if (mio_htre_getcontentlen(req) > 0)
/*const mio_bch_t* qpath = mio_htre_getqpath(req);*/ /*const mio_bch_t* qpath = mio_htre_getqpath(req);*/
if (mio_svc_htts_docgi(htts, csck, req, "") <= -1) goto oops; if (mio_svc_htts_docgi(htts, csck, req, "") <= -1) goto oops;
#if 0
/*
if (mio_comp_bcstr(qpath, "/testfunc", 0) == 0)
{
if (mio_svc_htts_sendcgi(htts, csck, test_func_handler, req) <= -1)
{
mio_htre_discardcontent (req);
mio_dev_sck_halt (csck);
}
}
else */if (mio_svc_htts_sendfile(htts, csck, qpath, 200, mth, mio_htre_getversion(req), (req->flags & MIO_HTRE_ATTR_KEEPALIVE)) <= -1)
{
mio_htre_discardcontent (req);
mio_dev_sck_halt (csck);
}
}
}
if (!(req->flags & MIO_HTRE_ATTR_KEEPALIVE) || mth == MIO_HTTP_CONNECT)
{
if (!peek)
{
//// task = mio_htts_entaskdisconnect(htts, client, MIO_NULL);
//// if (MIO_UNLIKELY(!task)) goto oops;
}
}
#endif
return 0; return 0;
oops: oops:
@ -289,7 +263,6 @@ static void fini_client (mio_svc_htts_cli_t* cli)
if (cli->rsrc) if (cli->rsrc)
{ {
printf ("TRYING TO KILL RSRC IN VARIABLE - ADDRESS %p\n", &cli->rsrc);
mio_svc_htts_rsrc_kill (cli->rsrc); mio_svc_htts_rsrc_kill (cli->rsrc);
cli->rsrc = MIO_NULL; cli->rsrc = MIO_NULL;
} }
@ -333,18 +306,19 @@ static int listener_on_read (mio_dev_sck_t* sck, const void* buf, mio_iolen_t le
if (len <= -1) if (len <= -1)
{ {
MIO_DEBUG3 (mio, "HTTS(%p) - unable to read client socket %p(%d)\n", cli->htts, sck, (int)sck->hnd); MIO_DEBUG3 (mio, "HTTS(%p) - unable to read client %p(%d)\n", cli->htts, sck, (int)sck->hnd);
goto oops; goto oops;
} }
if (len == 0) goto oops; if (len == 0)
{
MIO_DEBUG3 (mio, "HTTS(%p) - EOF on client %p(%d)\n", cli->htts, sck, (int)sck->hnd);
goto oops;
}
if ((x = mio_htrd_feed(cli->htrd, buf, len, &rem)) <= -1) if ((x = mio_htrd_feed(cli->htrd, buf, len, &rem)) <= -1)
{ {
/* in some cases, we may have to send some http response depending on the failure type */
/* BADRE -> bad request? */
printf ("** HTTS - client htrd feed failure socket(%p) - %d\n", sck, x); printf ("** HTTS - client htrd feed failure socket(%p) - %d\n", sck, x);
/* TODO: either send bad request or server failure ... */
goto oops; goto oops;
} }
@ -363,6 +337,7 @@ printf ("** HTTS - client htrd feed failure socket(%p) - %d\n", sck, x);
return 0; return 0;
oops: oops:
printf ("HALTING CLIENT SOCKEXXT %p\n", sck);
mio_dev_sck_halt (sck); mio_dev_sck_halt (sck);
return 0; return 0;
} }
@ -401,63 +376,64 @@ static void listener_on_connect (mio_dev_sck_t* sck)
static void listener_on_disconnect (mio_dev_sck_t* sck) static void listener_on_disconnect (mio_dev_sck_t* sck)
{ {
mio_t* mio = sck->mio;
mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(sck); mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(sck);
switch (MIO_DEV_SCK_GET_PROGRESS(sck)) switch (MIO_DEV_SCK_GET_PROGRESS(sck))
{ {
case MIO_DEV_SCK_CONNECTING: case MIO_DEV_SCK_CONNECTING:
/* only for connecting sockets */ /* only for connecting sockets */
MIO_DEBUG1 (sck->mio, "OUTGOING SESSION DISCONNECTED - FAILED TO CONNECT (%d) TO REMOTE SERVER\n", (int)sck->hnd); MIO_DEBUG1 (mio, "OUTGOING SESSION DISCONNECTED - FAILED TO CONNECT (%d) TO REMOTE SERVER\n", (int)sck->hnd);
break; break;
case MIO_DEV_SCK_CONNECTING_SSL: case MIO_DEV_SCK_CONNECTING_SSL:
/* only for connecting sockets */ /* only for connecting sockets */
MIO_DEBUG1 (sck->mio, "OUTGOING SESSION DISCONNECTED - FAILED TO SSL-CONNECT (%d) TO REMOTE SERVER\n", (int)sck->hnd); MIO_DEBUG1 (mio, "OUTGOING SESSION DISCONNECTED - FAILED TO SSL-CONNECT (%d) TO REMOTE SERVER\n", (int)sck->hnd);
break; break;
case MIO_DEV_SCK_CONNECTED: case MIO_DEV_SCK_CONNECTED:
/* only for connecting sockets */ /* only for connecting sockets */
MIO_DEBUG1 (sck->mio, "OUTGOING CLIENT CONNECTION GOT TORN DOWN %p(%d).......\n", (int)sck->hnd); MIO_DEBUG1 (mio, "OUTGOING CLIENT CONNECTION GOT TORN DOWN %p(%d).......\n", (int)sck->hnd);
break; break;
case MIO_DEV_SCK_LISTENING: case MIO_DEV_SCK_LISTENING:
MIO_DEBUG2 (sck->mio, "LISTNER SOCKET %p(%d) - SHUTTUING DOWN\n", sck, (int)sck->hnd); MIO_DEBUG2 (mio, "LISTNER SOCKET %p(%d) - SHUTTUING DOWN\n", sck, (int)sck->hnd);
break; break;
case MIO_DEV_SCK_ACCEPTING_SSL: /* special case. */ case MIO_DEV_SCK_ACCEPTING_SSL: /* special case. */
/* this progress code indicates that the ssl-level accept failed. /* this progress code indicates that the ssl-level accept failed.
* on_disconnected() with this code is called without corresponding on_connect(). * on_disconnected() with this code is called without corresponding on_connect().
* the cli extension are is not initialized yet */ * the cli extension are is not initialized yet */
MIO_ASSERT (sck->mio, sck != cli->sck); MIO_ASSERT (mio, sck != cli->sck);
MIO_ASSERT (sck->mio, cli->sck == cli->htts->lsck); /* the field is a copy of the extension are of the listener socket. so it should point to the listner socket */ MIO_ASSERT (mio, cli->sck == cli->htts->lsck); /* the field is a copy of the extension are of the listener socket. so it should point to the listner socket */
MIO_DEBUG2 (sck->mio, "LISTENER UNABLE TO SSL-ACCEPT CLIENT %p(%d) ....%p\n", sck, (int)sck->hnd); MIO_DEBUG2 (mio, "LISTENER UNABLE TO SSL-ACCEPT CLIENT %p(%d) ....%p\n", sck, (int)sck->hnd);
return; return;
case MIO_DEV_SCK_ACCEPTED: case MIO_DEV_SCK_ACCEPTED:
/* only for sockets accepted by the listeners. will never come here because /* only for sockets accepted by the listeners. will never come here because
* the disconnect call for such sockets have been changed in listener_on_connect() */ * the disconnect call for such sockets have been changed in listener_on_connect() */
MIO_DEBUG2 (sck->mio, "ACCEPTED CLIENT SOCKET %p(%d) GOT DISCONNECTED.......\n", sck, (int)sck->hnd); MIO_DEBUG2 (mio, "ACCEPTED CLIENT SOCKET %p(%d) GOT DISCONNECTED.......\n", sck, (int)sck->hnd);
break; break;
default: default:
MIO_DEBUG2 (sck->mio, "SOCKET %p(%d) DISCONNECTED AFTER ALL.......\n", sck, (int)sck->hnd); MIO_DEBUG2 (mio, "SOCKET %p(%d) DISCONNECTED AFTER ALL.......\n", sck, (int)sck->hnd);
break; break;
} }
if (sck == cli->htts->lsck) if (sck == cli->htts->lsck)
{ {
/* the listener socket has these fields set to NULL */ /* the listener socket has these fields set to NULL */
MIO_ASSERT (sck->mio, cli->htrd == MIO_NULL); MIO_ASSERT (mio, cli->htrd == MIO_NULL);
MIO_ASSERT (sck->mio, cli->sbuf == MIO_NULL); MIO_ASSERT (mio, cli->sbuf == MIO_NULL);
MIO_DEBUG2 (sck->mio, "HTTS(%p) - listener socket disconnect %p\n", cli->htts, sck); MIO_DEBUG2 (mio, "HTTS(%p) - listener socket disconnect %p\n", cli->htts, sck);
cli->htts->lsck = MIO_NULL; /* let the htts service forget about this listening socket */ cli->htts->lsck = MIO_NULL; /* let the htts service forget about this listening socket */
} }
else else
{ {
/* client socket */ /* client socket */
MIO_DEBUG2 (sck->mio, "HTTS(%p) - client socket disconnect %p\n", cli->htts, sck); MIO_DEBUG2 (mio, "HTTS(%p) - client socket disconnect %p\n", cli->htts, sck);
MIO_ASSERT (sck->mio, cli->sck == sck); MIO_ASSERT (mio, cli->sck == sck);
fini_client (cli); fini_client (cli);
} }
} }
@ -653,12 +629,14 @@ struct cgi_state_t
unsigned int over: 4; /* must be large enough to accomodate CGI_STATE_OVER_ALL */ unsigned int over: 4; /* must be large enough to accomodate CGI_STATE_OVER_ALL */
unsigned int keep_alive: 1; unsigned int keep_alive: 1;
unsigned int req_content_length_unlimited: 1; unsigned int req_content_length_unlimited: 1;
unsigned int ever_attempted_to_write_to_client; unsigned int ever_attempted_to_write_to_client: 1;
unsigned int client_disconnected: 1;
mio_oow_t req_content_length; /* client request content length */ mio_oow_t req_content_length; /* client request content length */
cgi_state_res_mode_t res_mode_to_cli; cgi_state_res_mode_t res_mode_to_cli;
mio_dev_sck_on_read_t client_org_on_read; mio_dev_sck_on_read_t client_org_on_read;
mio_dev_sck_on_write_t client_org_on_write; mio_dev_sck_on_write_t client_org_on_write;
mio_dev_sck_on_disconnect_t client_org_on_disconnect;
}; };
typedef struct cgi_state_t cgi_state_t; typedef struct cgi_state_t cgi_state_t;
@ -673,14 +651,12 @@ static void cgi_state_halt_participating_devices (cgi_state_t* cgi_state)
MIO_ASSERT (cgi_state->client->htts->mio, cgi_state->client != MIO_NULL); MIO_ASSERT (cgi_state->client->htts->mio, cgi_state->client != MIO_NULL);
MIO_ASSERT (cgi_state->client->htts->mio, cgi_state->client->sck != MIO_NULL); MIO_ASSERT (cgi_state->client->htts->mio, cgi_state->client->sck != MIO_NULL);
MIO_DEBUG4 (cgi_state->client->htts->mio, "HTTS(%p) - halting cgi state %p(client=%p,peer=%p)\n", cgi_state->client->htts, cgi_state, cgi_state->client->sck, cgi_state->peer); MIO_DEBUG4 (cgi_state->client->htts->mio, "HTTS(%p) - Halting participating devices in cgi state %p(client=%p,peer=%p)\n", cgi_state->client->htts, cgi_state, cgi_state->client->sck, cgi_state->peer);
mio_dev_sck_halt (cgi_state->client->sck); mio_dev_sck_halt (cgi_state->client->sck);
/* check for peer as it may not have been started */ /* check for peer as it may not have been started */
if (cgi_state->peer) mio_dev_pro_halt (cgi_state->peer); if (cgi_state->peer) mio_dev_pro_halt (cgi_state->peer);
/* TODO: when to destroy cgi_state? */
} }
static int cgi_state_write_to_client (cgi_state_t* cgi_state, const void* data, mio_iolen_t dlen) static int cgi_state_write_to_client (cgi_state_t* cgi_state, const void* data, mio_iolen_t dlen)
@ -719,6 +695,16 @@ static int cgi_state_writev_to_client (cgi_state_t* cgi_state, mio_iovec_t* iov,
return 0; return 0;
} }
static int cgi_state_write_last_chunk_to_client (cgi_state_t* cgi_state)
{
if (cgi_state->res_mode_to_cli == CGI_STATE_RES_MODE_CHUNKED &&
cgi_state_write_to_client(cgi_state, "0\r\n\r\n", 5) <= -1) return -1;
if (!cgi_state->keep_alive && cgi_state_write_to_client(cgi_state, MIO_NULL, 0) <= -1) return -1;
return 0;
}
static int cgi_state_write_to_peer (cgi_state_t* cgi_state, const void* data, mio_iolen_t dlen) static int cgi_state_write_to_peer (cgi_state_t* cgi_state, const void* data, mio_iolen_t dlen)
{ {
cgi_state->num_pending_writes_to_peer++; cgi_state->num_pending_writes_to_peer++;
@ -763,12 +749,12 @@ static MIO_INLINE void cgi_state_mark_over (cgi_state_t* cgi_state, int over_bit
if (!(old_over & CGI_STATE_OVER_READ_FROM_CLIENT) && (cgi_state->over & CGI_STATE_OVER_READ_FROM_CLIENT)) if (!(old_over & CGI_STATE_OVER_READ_FROM_CLIENT) && (cgi_state->over & CGI_STATE_OVER_READ_FROM_CLIENT))
{ {
mio_dev_sck_read (cgi_state->client->sck, 0); /* TODO: error handling */ if (mio_dev_sck_read(cgi_state->client->sck, 0) <= -1) mio_dev_sck_halt (cgi_state->client->sck);
} }
if (!(old_over & CGI_STATE_OVER_READ_FROM_PEER) && (cgi_state->over & CGI_STATE_OVER_READ_FROM_PEER)) if (!(old_over & CGI_STATE_OVER_READ_FROM_PEER) && (cgi_state->over & CGI_STATE_OVER_READ_FROM_PEER))
{ {
if (cgi_state->peer) mio_dev_pro_read (cgi_state->peer, MIO_DEV_PRO_OUT, 0); /* TODO: error handling */ if (cgi_state->peer && mio_dev_pro_read(cgi_state->peer, MIO_DEV_PRO_OUT, 0) <= -1) mio_dev_pro_halt (cgi_state->peer);
} }
if (old_over != CGI_STATE_OVER_ALL && cgi_state->over == CGI_STATE_OVER_ALL) if (old_over != CGI_STATE_OVER_ALL && cgi_state->over == CGI_STATE_OVER_ALL)
@ -779,11 +765,11 @@ static MIO_INLINE void cgi_state_mark_over (cgi_state_t* cgi_state, int over_bit
if (cgi_state->keep_alive) if (cgi_state->keep_alive)
{ {
/* how to arrange to delete this cgi_state object and put the socket back to the normal waiting state??? */ /* how to arrange to delete this cgi_state object and put the socket back to the normal waiting state??? */
MIO_ASSERT (cgi_state->htts->mio, cgi_state->client->rsrc == cgi_state); MIO_ASSERT (cgi_state->htts->mio, cgi_state->client->rsrc == (mio_svc_htts_rsrc_t*)cgi_state);
printf ("DEASSIGNING FROM THE MAIN CLIENT RSRC... state -> %p VARIABEL ADDRESSS %p\n", cgi_state->client->rsrc, &cgi_state->client->rsrc); printf ("DETACHING FROM THE MAIN CLIENT RSRC... state -> %p\n", cgi_state->client->rsrc);
MIO_SVC_HTTS_RSRC_DEASSIGN (cgi_state->client->rsrc); MIO_SVC_HTTS_RSRC_DETACH (cgi_state->client->rsrc);
printf ("AFTER DEASSIGNING FROM THE MAIN CLIENT RSRC... state -> %p VARIABEL ADDRESSS %p\n", cgi_state->client->rsrc, &cgi_state->client->rsrc); /* cgi_state must not be access from here down as it could have been destroyed */
} }
else else
{ {
@ -826,11 +812,26 @@ printf ("**** CGI_STATE_ON_KILL \n");
cgi_state->client_org_on_write = MIO_NULL; cgi_state->client_org_on_write = MIO_NULL;
} }
mio_htrd_setrecbs (cgi_state->client->htrd, &client_htrd_recbs); /* restore the callbacks */
if (mio_dev_sck_read (cgi_state->client->sck, 1) <= -1) if (cgi_state->client_org_on_disconnect)
{ {
mio_dev_sck_halt (cgi_state->client->sck); cgi_state->client->sck->on_disconnect = cgi_state->client_org_on_disconnect;
cgi_state->client_org_on_disconnect = MIO_NULL;
} }
mio_htrd_setrecbs (cgi_state->client->htrd, &client_htrd_recbs); /* restore the callbacks */
if (!cgi_state->client_disconnected)
{
printf ("ENABLING INPUT WATCHING on CLIENT %p. \n", cgi_state->client->sck);
if (!cgi_state->keep_alive || mio_dev_sck_read(cgi_state->client->sck, 1) <= -1)
{
printf ("FAILED TO ENABLE INPUT WATCHING on CLINET %p. SO HALTING CLIENT SOCKET>>>>>>>>>>>>>\n", cgi_state->client->sck);
mio_dev_sck_halt (cgi_state->client->sck);
}
}
printf ("**** CGI_STATE_ON_KILL DONE\n");
} }
static void cgi_peer_on_close (mio_dev_pro_t* pro, mio_dev_pro_sid_t sid) static void cgi_peer_on_close (mio_dev_pro_t* pro, mio_dev_pro_sid_t sid)
@ -846,8 +847,21 @@ static void cgi_peer_on_close (mio_dev_pro_t* pro, mio_dev_pro_sid_t sid)
case MIO_DEV_PRO_MASTER: case MIO_DEV_PRO_MASTER:
MIO_DEBUG3 (mio, "HTTS(%p) - peer %p(pid=%d) closing master\n", cgi_state->client->htts, pro, (int)pro->child_pid); MIO_DEBUG3 (mio, "HTTS(%p) - peer %p(pid=%d) closing master\n", cgi_state->client->htts, pro, (int)pro->child_pid);
cgi_state->peer = MIO_NULL; /* clear this peer from the state */ cgi_state->peer = MIO_NULL; /* clear this peer from the state */
printf ("DEASSIGNING 11.....................%p %d\n", cgi_peer->state, (int)cgi_peer->state->rsrc_refcnt);
MIO_SVC_HTTS_RSRC_DEASSIGN (cgi_peer->state); MIO_ASSERT (mio, cgi_peer->state != MIO_NULL);
printf ("DETACHING FROM CGI PEER DEVICE.....................%p %d\n", cgi_peer->state, (int)cgi_peer->state->rsrc_refcnt);
MIO_SVC_HTTS_RSRC_DETACH (cgi_peer->state);
if (cgi_state->peer_htrd)
{
/* once this peer device is closed, peer's htrd is also never used.
* it's safe to detach the extra information attached on the htrd object. */
cgi_peer = mio_htrd_getxtn(cgi_state->peer_htrd);
MIO_ASSERT (mio, cgi_peer->state != MIO_NULL);
printf ("DETACHING FROM CGI PEER HTRD.....................%p %d\n", cgi_peer->state, (int)cgi_peer->state->rsrc_refcnt);
MIO_SVC_HTTS_RSRC_DETACH (cgi_peer->state);
}
break; break;
case MIO_DEV_PRO_OUT: case MIO_DEV_PRO_OUT:
@ -856,15 +870,11 @@ printf ("DEASSIGNING 11.....................%p %d\n", cgi_peer->state, (int)cg
if (!(cgi_state->over & CGI_STATE_OVER_READ_FROM_PEER)) if (!(cgi_state->over & CGI_STATE_OVER_READ_FROM_PEER))
{ {
if (cgi_state->res_mode_to_cli == CGI_STATE_RES_MODE_CHUNKED && if (cgi_state_write_last_chunk_to_client(cgi_state) <= -1)
cgi_state_write_to_client(cgi_state, "0\r\n\r\n", 5) <= -1)
{
cgi_state_halt_participating_devices (cgi_state); cgi_state_halt_participating_devices (cgi_state);
} else
cgi_state_mark_over (cgi_state, CGI_STATE_OVER_READ_FROM_PEER);
cgi_state_mark_over (cgi_state, CGI_STATE_OVER_READ_FROM_PEER);
} }
break; break;
case MIO_DEV_PRO_IN: case MIO_DEV_PRO_IN:
@ -903,16 +913,8 @@ static int cgi_peer_on_read (mio_dev_pro_t* pro, mio_dev_pro_sid_t sid, const vo
/* the cgi script could be misbehaviing. /* the cgi script could be misbehaviing.
* it still has to read more but EOF is read. * it still has to read more but EOF is read.
* otherwise client_peer_htrd_poke() should have been called */ * otherwise client_peer_htrd_poke() should have been called */
if (cgi_state_write_last_chunk_to_client(cgi_state) <= -1) goto oops;
if (cgi_state->res_mode_to_cli == CGI_STATE_RES_MODE_CHUNKED &&
cgi_state_write_to_client(cgi_state, "0\r\n\r\n", 5) <= -1) goto oops;
cgi_state_mark_over (cgi_state, CGI_STATE_OVER_READ_FROM_PEER); cgi_state_mark_over (cgi_state, CGI_STATE_OVER_READ_FROM_PEER);
printf ("DEASSIGNING 33.....................peer %p state %p %d\n", cgi_peer, cgi_peer->state, (int)cgi_peer->state->rsrc_refcnt);
/* peer_htrd isn't needed any longer. unlink the cgi state from it */
cgi_peer = mio_htrd_getxtn(cgi_state->peer_htrd);
MIO_SVC_HTTS_RSRC_DEASSIGN (cgi_peer->state);
} }
} }
else else
@ -924,9 +926,14 @@ printf ("DEASSIGNING 33.....................peer %p state %p %d\n", cgi_peer,
if (mio_htrd_feed(cgi_state->peer_htrd, data, dlen, &rem) <= -1) if (mio_htrd_feed(cgi_state->peer_htrd, data, dlen, &rem) <= -1)
{ {
MIO_DEBUG3 (mio, "HTTPS(%p) - unable to feed peer into to htrd - peer %p(pid=%u)\n", cgi_state->htts, pro, (unsigned int)pro->child_pid); MIO_DEBUG3 (mio, "HTTPS(%p) - unable to feed peer into to htrd - peer %p(pid=%u)\n", cgi_state->htts, pro, (unsigned int)pro->child_pid);
if (!cgi_state->ever_attempted_to_write_to_client && if (!cgi_state->ever_attempted_to_write_to_client &&
!(cgi_state->over & CGI_STATE_OVER_WRITE_TO_CLIENT) && !(cgi_state->over & CGI_STATE_OVER_WRITE_TO_CLIENT))
cgi_state_send_final_status_to_client(cgi_state, 500) <= -1) goto oops; {
cgi_state_send_final_status_to_client (cgi_state, 500); /* don't care about error because it jumps to oops below anyway */
}
goto oops;
} }
if (rem > 0) if (rem > 0)
@ -935,14 +942,6 @@ printf ("DEASSIGNING 33.....................peer %p state %p %d\n", cgi_peer,
printf ("AAAAAAAAAAAAAAAAAa EEEEEXcessive DATA..................\n"); printf ("AAAAAAAAAAAAAAAAAa EEEEEXcessive DATA..................\n");
/* TODO: or drop this request?? */ /* TODO: or drop this request?? */
} }
if (cgi_state->over & CGI_STATE_OVER_READ_FROM_PEER)
{
printf ("DEASSIGNING 22.....................peer %p state %p %d\n", cgi_peer, cgi_peer->state, (int)cgi_peer->state->rsrc_refcnt);
/* peer_htrd isn't needed any longer. unlink the cgi state from it */
cgi_peer = mio_htrd_getxtn(cgi_state->peer_htrd);
MIO_SVC_HTTS_RSRC_DEASSIGN (cgi_peer->state);
}
} }
return 0; return 0;
@ -1026,9 +1025,7 @@ printf ("CGI PEER HTRD PEEK...\n");
break; break;
case CGI_STATE_RES_MODE_LENGTH: case CGI_STATE_RES_MODE_LENGTH:
/* TODO: Keep-Alive if explicit in http/1.0 . if (mio_becs_cat(cli->sbuf, (cgi_state->keep_alive? "Connection: keep-alive\r\n": "Connection: close\r\n")) == (mio_oow_t)-1) return -1;
* Keep-Alive not needed if http/1.1 or later */
break;
} }
if (mio_becs_cat(cli->sbuf, "\r\n") == (mio_oow_t)-1) return -1; if (mio_becs_cat(cli->sbuf, "\r\n") == (mio_oow_t)-1) return -1;
@ -1043,11 +1040,7 @@ static int cgi_peer_htrd_poke (mio_htrd_t* htrd, mio_htre_t* req)
printf (">> PEER RESPONSE COMPLETED\n"); printf (">> PEER RESPONSE COMPLETED\n");
if (cgi_state->res_mode_to_cli == CGI_STATE_RES_MODE_CHUNKED && if (cgi_state_write_last_chunk_to_client(cgi_state) <= -1) return -1;
cgi_state_write_to_client(cgi_state, "0\r\n\r\n", 5) <= -1) return -1;
/* indicate EOF to the client */
if (cgi_state_write_to_client(cgi_state, MIO_NULL, 0) <= -1) return -1;
cgi_state_mark_over (cgi_state, CGI_STATE_OVER_READ_FROM_PEER); cgi_state_mark_over (cgi_state, CGI_STATE_OVER_READ_FROM_PEER);
return 0; return 0;
@ -1198,6 +1191,14 @@ oops:
return 0; return 0;
} }
static void cgi_client_on_disconnect (mio_dev_sck_t* sck)
{
mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(sck);
cgi_state_t* cgi_state = (cgi_state_t*)cli->rsrc;
cgi_state->client_disconnected = 1;
listener_on_disconnect (sck);
}
static int cgi_client_on_read (mio_dev_sck_t* sck, const void* buf, mio_iolen_t len, const mio_skad_t* srcaddr) static int cgi_client_on_read (mio_dev_sck_t* sck, const void* buf, mio_iolen_t len, const mio_skad_t* srcaddr)
{ {
mio_t* mio = sck->mio; mio_t* mio = sck->mio;
@ -1324,6 +1325,71 @@ static MIO_INLINE int get_request_content_length (mio_htre_t* req, mio_oow_t* le
return 0; /* limited to the length set in *len */ return 0; /* limited to the length set in *len */
} }
struct cgi_peer_fork_ctx_t
{
mio_svc_htts_cli_t* cli;
mio_htre_t* req;
const mio_bch_t* docroot;
};
typedef struct cgi_peer_fork_ctx_t cgi_peer_fork_ctx_t;
static int cgi_peer_on_fork (mio_dev_pro_t* pro, void* fork_ctx)
{
/*mio_t* mio = pro->mio;*/ /* in this callback, the pro device is not fully up. however, the mio field is guaranteed to be available */
cgi_peer_fork_ctx_t* fc = (cgi_peer_fork_ctx_t*)fork_ctx;
mio_oow_t content_length;
mio_bch_t tmp[128];
const mio_bch_t* qparam;
qparam = mio_htre_getqparam(fc->req);
clearenv ();
setenv ("GATEWAY_INTERFACE", "CGI/1.1", 1);
/////////
printf (">>>>>>>>>> %d pro->mio %p\n",
mio_fmttobcstr (pro->mio, tmp, MIO_COUNTOF(tmp), "HTTP/%d.%d", (int)mio_htre_getmajorversion(fc->req), (int)mio_htre_getminorversion(fc->req)), pro->mio);
////////
setenv ("SERVER_PROTOCOL", tmp, 1);
//setenv ("SCRIPT_FILENAME",
//setenv ("SCRIPT_NAME",
setenv ("DOCUMENT_ROOT", fc->docroot, 1);
setenv ("REQUEST_METHOD", mio_htre_getqmethodname(fc->req), 1);
setenv ("REQUEST_URI", mio_htre_getqpath(fc->req), 1);
if (qparam) setenv ("QUERY_STRING", qparam, 1);
if (get_request_content_length(fc->req, &content_length) == 0)
{
mio_fmt_uintmax_to_bcstr(tmp, MIO_COUNTOF(tmp), content_length, 10, 0, '\0', MIO_NULL);
setenv ("CONTENT_LENGTH", tmp, 1);
}
else
{
/* content length unknown, neither is it 0 - this is not standard */
setenv ("CONTENT_LENGTH", "-1", 1);
}
setenv ("SERVER_SOFTWARE", fc->cli->htts->server_name, 1);
#if 0
setenv ("SERVER_PORT",
setenv ("SERVER_ADDR",
setenv ("SERVER_NAME", /* server host name */
setenv ("REMOTE_PORT",
setenv ("REMOTE_ADDR",
#endif
//mio_htre_walkheaders(req,
/* [NOTE] trailers are not available when this cgi resource is started. let's not call mio_htre_walktrailers() */
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)
{ {
mio_t* mio = htts->mio; mio_t* mio = htts->mio;
@ -1331,16 +1397,24 @@ int mio_svc_htts_docgi (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* r
cgi_state_t* cgi_state = MIO_NULL; cgi_state_t* cgi_state = MIO_NULL;
cgi_peer_xtn_t* cgi_peer; cgi_peer_xtn_t* cgi_peer;
mio_dev_pro_make_t mi; mio_dev_pro_make_t mi;
cgi_peer_fork_ctx_t fc;
/* ensure that you call this function before any contents is received */ /* ensure that you call this function before any contents is received */
MIO_ASSERT (mio, mio_htre_getcontentlen(req) == 0); MIO_ASSERT (mio, mio_htre_getcontentlen(req) == 0);
MIO_MEMSET (&fc, 0, MIO_SIZEOF(fc));
fc.cli = cli;
fc.req = req;
fc.docroot = docroot;
MIO_MEMSET (&mi, 0, MIO_SIZEOF(mi)); 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.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 = mio_htre_getqpath(req); /* TODO: combine it with docroot */
mi.on_read = cgi_peer_on_read; mi.on_read = cgi_peer_on_read;
mi.on_write = cgi_peer_on_write; mi.on_write = cgi_peer_on_write;
mi.on_close = cgi_peer_on_close; mi.on_close = cgi_peer_on_close;
mi.on_fork = cgi_peer_on_fork;
mi.fork_ctx = &fc;
cgi_state = (cgi_state_t*)mio_svc_htts_rsrc_make(htts, MIO_SIZEOF(*cgi_state), cgi_state_on_kill); cgi_state = (cgi_state_t*)mio_svc_htts_rsrc_make(htts, MIO_SIZEOF(*cgi_state), cgi_state_on_kill);
if (MIO_UNLIKELY(!cgi_state)) goto oops; if (MIO_UNLIKELY(!cgi_state)) goto oops;
@ -1353,11 +1427,13 @@ int mio_svc_htts_docgi (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* r
cgi_state->client_org_on_read = csck->on_read; cgi_state->client_org_on_read = csck->on_read;
cgi_state->client_org_on_write = csck->on_write; cgi_state->client_org_on_write = csck->on_write;
cgi_state->client_org_on_disconnect = csck->on_disconnect;
csck->on_read = cgi_client_on_read; csck->on_read = cgi_client_on_read;
csck->on_write = cgi_client_on_write; csck->on_write = cgi_client_on_write;
csck->on_disconnect = cgi_client_on_disconnect;
MIO_ASSERT (mio, cli->rsrc == MIO_NULL); MIO_ASSERT (mio, cli->rsrc == MIO_NULL);
MIO_SVC_HTTS_RSRC_ASSIGN (cgi_state, cli->rsrc); MIO_SVC_HTTS_RSRC_ATTACH (cgi_state, cli->rsrc);
/* TODO: create cgi environment variables... */ /* TODO: create cgi environment variables... */
/* TODO: /* TODO:
@ -1372,7 +1448,7 @@ int mio_svc_htts_docgi (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* r
cgi_state->peer = mio_dev_pro_make(mio, MIO_SIZEOF(*cgi_peer), &mi); cgi_state->peer = mio_dev_pro_make(mio, MIO_SIZEOF(*cgi_peer), &mi);
if (MIO_UNLIKELY(!cgi_state->peer)) goto oops; if (MIO_UNLIKELY(!cgi_state->peer)) goto oops;
cgi_peer = mio_dev_pro_getxtn(cgi_state->peer); cgi_peer = mio_dev_pro_getxtn(cgi_state->peer);
MIO_SVC_HTTS_RSRC_ASSIGN (cgi_state, cgi_peer->state); MIO_SVC_HTTS_RSRC_ATTACH (cgi_state, cgi_peer->state);
cgi_state->peer_htrd = mio_htrd_open(mio, MIO_SIZEOF(*cgi_peer)); cgi_state->peer_htrd = mio_htrd_open(mio, MIO_SIZEOF(*cgi_peer));
if (MIO_UNLIKELY(!cgi_state->peer_htrd)) goto oops; if (MIO_UNLIKELY(!cgi_state->peer_htrd)) goto oops;
@ -1380,7 +1456,7 @@ int mio_svc_htts_docgi (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* r
mio_htrd_setrecbs (cgi_state->peer_htrd, &cgi_peer_htrd_recbs); mio_htrd_setrecbs (cgi_state->peer_htrd, &cgi_peer_htrd_recbs);
cgi_peer = mio_htrd_getxtn(cgi_state->peer_htrd); cgi_peer = mio_htrd_getxtn(cgi_state->peer_htrd);
MIO_SVC_HTTS_RSRC_ASSIGN (cgi_state, cgi_peer->state); MIO_SVC_HTTS_RSRC_ATTACH (cgi_state, cgi_peer->state);
#if !defined(CGI_ALLOW_UNLIMITED_REQ_CONTENT_LENGTH) #if !defined(CGI_ALLOW_UNLIMITED_REQ_CONTENT_LENGTH)
if (cgi_state->req_content_length_unlimited) if (cgi_state->req_content_length_unlimited)

View File

@ -178,8 +178,8 @@ struct mio_svc_htts_rsrc_t
MIO_SVC_HTTS_RSRC_HEADER; MIO_SVC_HTTS_RSRC_HEADER;
}; };
#define MIO_SVC_HTTS_RSRC_ASSIGN(rsrc, var) do { (var) = (rsrc); ++(rsrc)->rsrc_refcnt; } while(0) #define MIO_SVC_HTTS_RSRC_ATTACH(rsrc, var) do { (var) = (rsrc); ++(rsrc)->rsrc_refcnt; } while(0)
#define MIO_SVC_HTTS_RSRC_DEASSIGN(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) #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)
/* -------------------------------------------------------------- */ /* -------------------------------------------------------------- */
#if defined(__cplusplus) #if defined(__cplusplus)

View File

@ -59,6 +59,11 @@ typedef void (*mio_dev_pro_on_close_t) (
mio_dev_pro_sid_t sid mio_dev_pro_sid_t sid
); );
typedef int (*mio_dev_pro_on_fork_t) (
mio_dev_pro_t* dev,
void* fork_ctx
);
struct mio_dev_pro_t struct mio_dev_pro_t
{ {
MIO_DEV_HEADER; MIO_DEV_HEADER;
@ -121,6 +126,8 @@ struct mio_dev_pro_make_t
mio_dev_pro_on_write_t on_write; /* mandatory */ mio_dev_pro_on_write_t on_write; /* mandatory */
mio_dev_pro_on_read_t on_read; /* mandatory */ mio_dev_pro_on_read_t on_read; /* mandatory */
mio_dev_pro_on_close_t on_close; /* optional */ mio_dev_pro_on_close_t on_close; /* optional */
mio_dev_pro_on_fork_t on_fork; /* optional */
void* fork_ctx;
}; };

View File

@ -1045,17 +1045,18 @@ int mio_dev_watch (mio_dev_t* dev, mio_dev_watch_cmd_t cmd, int events)
break; break;
case MIO_DEV_WATCH_STOP: case MIO_DEV_WATCH_STOP:
if (!(dev->dev_cap & DEV_CAP_ALL_WATCHED)) return 0; /* the device is not being watched */
events = 0; /* override events */ events = 0; /* override events */
mux_cmd = MIO_SYS_MUX_CMD_DELETE; mux_cmd = MIO_SYS_MUX_CMD_DELETE;
break; dev_cap = dev->dev_cap & ~(DEV_CAP_ALL_WATCHED);
goto ctrl_mux;
default: default:
mio_seterrnum (dev->mio, MIO_EINVAL); mio_seterrnum (dev->mio, MIO_EINVAL);
return -1; return -1;
} }
dev_cap = dev->dev_cap; dev_cap = dev->dev_cap & ~(DEV_CAP_ALL_WATCHED);
dev_cap &= ~(DEV_CAP_ALL_WATCHED);
/* this function honors MIO_DEV_EVENT_IN and MIO_DEV_EVENT_OUT only /* this function honors MIO_DEV_EVENT_IN and MIO_DEV_EVENT_OUT only
* as valid input event bits. it intends to provide simple abstraction * as valid input event bits. it intends to provide simple abstraction
@ -1081,6 +1082,7 @@ int mio_dev_watch (mio_dev_t* dev, mio_dev_watch_cmd_t cmd, int events)
} }
else else
{ {
ctrl_mux:
if (mio_sys_ctrlmux(mio, mux_cmd, dev, dev_cap) <= -1) return -1; if (mio_sys_ctrlmux(mio, mux_cmd, dev, dev_cap) <= -1) return -1;
} }

View File

@ -31,7 +31,7 @@
* support \\?\UNC\server\path which is equivalent to \\server\path. * support \\?\UNC\server\path which is equivalent to \\server\path.
* */ * */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* WCS IMPLEMENTATION */ /* UCH IMPLEMENTATION */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
#if 0 #if 0
@ -335,7 +335,7 @@ mio_oow_t mio_canon_ucstr_path (const mio_uch_t* path, mio_uch_t* canon, int fla
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* MBS IMPLEMENTATION */ /* BCH IMPLEMENTATION */
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
#if 0 #if 0

View File

@ -128,11 +128,12 @@ oops:
return -1; return -1;
} }
static pid_t standard_fork_and_exec (mio_t* mio, int pfds[], int flags, param_t* param) static pid_t standard_fork_and_exec (mio_dev_pro_t* dev, int pfds[], mio_dev_pro_make_t* mi, param_t* param)
{ {
mio_t* mio = dev->mio;
pid_t pid; pid_t pid;
pid = fork (); pid = fork();
if (pid == -1) if (pid == -1)
{ {
mio_seterrwithsyserr (mio, 0, errno); mio_seterrwithsyserr (mio, 0, errno);
@ -146,8 +147,9 @@ static pid_t standard_fork_and_exec (mio_t* mio, int pfds[], int flags, param_t*
mio_syshnd_t devnull = MIO_SYSHND_INVALID; mio_syshnd_t devnull = MIO_SYSHND_INVALID;
/* TODO: close all uneeded fds */ /* TODO: close all uneeded fds */
if (mi->on_fork) mi->on_fork (dev, mi->fork_ctx);
if (flags & MIO_DEV_PRO_WRITEIN) if (mi->flags & MIO_DEV_PRO_WRITEIN)
{ {
/* slave should read */ /* slave should read */
close (pfds[1]); close (pfds[1]);
@ -160,7 +162,7 @@ static pid_t standard_fork_and_exec (mio_t* mio, int pfds[], int flags, param_t*
pfds[0] = MIO_SYSHND_INVALID; pfds[0] = MIO_SYSHND_INVALID;
} }
if (flags & MIO_DEV_PRO_READOUT) if (mi->flags & MIO_DEV_PRO_READOUT)
{ {
/* slave should write */ /* slave should write */
close (pfds[2]); close (pfds[2]);
@ -168,7 +170,7 @@ static pid_t standard_fork_and_exec (mio_t* mio, int pfds[], int flags, param_t*
if (dup2(pfds[3], 1) == -1) goto slave_oops; if (dup2(pfds[3], 1) == -1) goto slave_oops;
if (flags & MIO_DEV_PRO_ERRTOOUT) if (mi->flags & MIO_DEV_PRO_ERRTOOUT)
{ {
if (dup2(pfds[3], 2) == -1) goto slave_oops; if (dup2(pfds[3], 2) == -1) goto slave_oops;
} }
@ -177,14 +179,14 @@ static pid_t standard_fork_and_exec (mio_t* mio, int pfds[], int flags, param_t*
pfds[3] = MIO_SYSHND_INVALID; pfds[3] = MIO_SYSHND_INVALID;
} }
if (flags & MIO_DEV_PRO_READERR) if (mi->flags & MIO_DEV_PRO_READERR)
{ {
close (pfds[4]); close (pfds[4]);
pfds[4] = MIO_SYSHND_INVALID; pfds[4] = MIO_SYSHND_INVALID;
if (dup2(pfds[5], 2) == -1) goto slave_oops; if (dup2(pfds[5], 2) == -1) goto slave_oops;
if (flags & MIO_DEV_PRO_OUTTOERR) if (mi->flags & MIO_DEV_PRO_OUTTOERR)
{ {
if (dup2(pfds[5], 1) == -1) goto slave_oops; if (dup2(pfds[5], 1) == -1) goto slave_oops;
} }
@ -193,9 +195,9 @@ static pid_t standard_fork_and_exec (mio_t* mio, int pfds[], int flags, param_t*
pfds[5] = MIO_SYSHND_INVALID; pfds[5] = MIO_SYSHND_INVALID;
} }
if ((flags & MIO_DEV_PRO_INTONUL) || if ((mi->flags & MIO_DEV_PRO_INTONUL) ||
(flags & MIO_DEV_PRO_OUTTONUL) || (mi->flags & MIO_DEV_PRO_OUTTONUL) ||
(flags & MIO_DEV_PRO_ERRTONUL)) (mi->flags & MIO_DEV_PRO_ERRTONUL))
{ {
#if defined(O_LARGEFILE) #if defined(O_LARGEFILE)
devnull = open("/dev/null", O_RDWR | O_LARGEFILE, 0); devnull = open("/dev/null", O_RDWR | O_LARGEFILE, 0);
@ -270,7 +272,7 @@ static int dev_pro_make_master (mio_dev_t* dev, void* ctx)
if (make_param(mio, info->cmd, info->flags, &param) <= -1) goto oops; if (make_param(mio, info->cmd, info->flags, &param) <= -1) goto oops;
/* TODO: more advanced fork and exec .. */ /* TODO: more advanced fork and exec .. */
pid = standard_fork_and_exec(mio, pfds, info->flags, &param); pid = standard_fork_and_exec(dev, pfds, info, &param);
if (pid <= -1) if (pid <= -1)
{ {
free_param (mio, &param); free_param (mio, &param);
@ -582,6 +584,7 @@ static int dev_pro_write_slave (mio_dev_t* dev, const void* data, mio_iolen_t* l
//mio_dev_halt (dev); /* halt this slave device to indicate EOF on the lower-level handle */* //mio_dev_halt (dev); /* halt this slave device to indicate EOF on the lower-level handle */*
if (MIO_LIKELY(pro->pfd != MIO_SYSHND_INVALID)) /* halt() doesn't close the pipe immediately. so close the underlying pipe */ if (MIO_LIKELY(pro->pfd != MIO_SYSHND_INVALID)) /* halt() doesn't close the pipe immediately. so close the underlying pipe */
{ {
mio_dev_watch (dev, MIO_DEV_WATCH_STOP, 0);
close (pro->pfd); close (pro->pfd);
pro->pfd = MIO_SYSHND_INVALID; pro->pfd = MIO_SYSHND_INVALID;
} }
@ -618,6 +621,7 @@ static int dev_pro_writev_slave (mio_dev_t* dev, const mio_iovec_t* iov, mio_iol
/*mio_dev_halt (dev);*/ /* halt this slave device to indicate EOF on the lower-level handle */ /*mio_dev_halt (dev);*/ /* halt this slave device to indicate EOF on the lower-level handle */
if (MIO_LIKELY(pro->pfd != MIO_SYSHND_INVALID)) /* halt() doesn't close the pipe immediately. so close the underlying pipe */ if (MIO_LIKELY(pro->pfd != MIO_SYSHND_INVALID)) /* halt() doesn't close the pipe immediately. so close the underlying pipe */
{ {
mio_dev_watch (dev, MIO_DEV_WATCH_STOP, 0);
close (pro->pfd); close (pro->pfd);
pro->pfd = MIO_SYSHND_INVALID; pro->pfd = MIO_SYSHND_INVALID;
} }

View File

@ -4,4 +4,6 @@ echo "Content-Type: text/plain"
echo "Custom-Attribute: abcdef" echo "Custom-Attribute: abcdef"
echo echo
printenv
exec cat /home/hyung-hwan/projects/hawk/lib/run.c exec cat /home/hyung-hwan/projects/hawk/lib/run.c

View File

@ -5,8 +5,8 @@
echo "Content-Type: text/plain" echo "Content-Type: text/plain"
echo echo
while read x while IFS= read -r x
do do
echo $x echo "$x"
done done
##echo "<<EOF>>" echo "<<EOF>>"

22
mio/t/e.sh Executable file
View File

@ -0,0 +1,22 @@
#!/bin/sh
## curl -v --http1.0 --data-binary @/etc/group --http1.1 http://127.0.0.1:9988/home/hyung-hwan/projects/mio/t/d.sh
echo "Content-Type: text/plain"
echo
if IFS= read -r x
then
q="${x}"
while IFS= read -r x
do
q="${q}
${x}"
done
else
q = ""
fi
sleep 3
printf "%s" "$q"
##echo "<<EOF>>"

View File

@ -6,7 +6,11 @@ BEGIN {
msg = b"GET /home/hyung-hwan/projects/mio/t/b.sh HTTP/1.1\r\n\ msg = b"GET /home/hyung-hwan/projects/mio/t/b.sh HTTP/1.1\r\n\
Host: www.google.com\r\n\ Host: www.google.com\r\n\
Connection: Keep-Alive\r\n\r\n"; Connection: close\r\n\r\n";
#msg = b"GET /home/hyung-hwan/projects/mio/t/b.sh HTTP/1.1\r\n\
#Host: www.google.com\r\n\
#Connection: Keep-Alive\r\n\r\n";
sys::write (x, msg); sys::write (x, msg);