still working on cgi handling in http server
This commit is contained in:
parent
362ae444fc
commit
fc26f4a6c3
@ -472,7 +472,7 @@ static void send_icmp (mio_dev_sck_t* dev, mio_uint16_t seq)
|
|||||||
icmphdr->u.echo.seq = mio_hton16(seq);
|
icmphdr->u.echo.seq = mio_hton16(seq);
|
||||||
|
|
||||||
memset (&buf[MIO_SIZEOF(*icmphdr)], 'A', MIO_SIZEOF(buf) - MIO_SIZEOF(*icmphdr));
|
memset (&buf[MIO_SIZEOF(*icmphdr)], 'A', MIO_SIZEOF(buf) - MIO_SIZEOF(*icmphdr));
|
||||||
icmphdr->checksum = mio_checksumip (icmphdr, MIO_SIZEOF(buf));
|
icmphdr->checksum = mio_checksum_ip(icmphdr, MIO_SIZEOF(buf));
|
||||||
|
|
||||||
if (mio_dev_sck_write(dev, buf, MIO_SIZEOF(buf), MIO_NULL, &dstaddr) <= -1)
|
if (mio_dev_sck_write(dev, buf, MIO_SIZEOF(buf), MIO_NULL, &dstaddr) <= -1)
|
||||||
{
|
{
|
||||||
|
@ -254,6 +254,10 @@ static int init_client (mio_svc_htts_cli_t* cli, mio_dev_sck_t* sck)
|
|||||||
cli->htrd = mio_htrd_open(sck->mio, MIO_SIZEOF(*htrdxtn));
|
cli->htrd = mio_htrd_open(sck->mio, MIO_SIZEOF(*htrdxtn));
|
||||||
if (MIO_UNLIKELY(!cli->htrd)) goto oops;
|
if (MIO_UNLIKELY(!cli->htrd)) goto oops;
|
||||||
|
|
||||||
|
/* With MIO_HTRD_TRAILERS, htrd stores trailers in a separate place.
|
||||||
|
* Otherwise, it is merged to the headers. */
|
||||||
|
/*mio_htrd_setopt (cli->htrd, MIO_HTRD_REQUEST | MIO_HTRD_TRAILERS);*/
|
||||||
|
|
||||||
cli->sbuf = mio_becs_open(sck->mio, 0, 2048);
|
cli->sbuf = mio_becs_open(sck->mio, 0, 2048);
|
||||||
if (MIO_UNLIKELY(!cli->sbuf)) goto oops;
|
if (MIO_UNLIKELY(!cli->sbuf)) goto oops;
|
||||||
|
|
||||||
@ -616,6 +620,13 @@ typedef enum cgi_state_res_mode_t cgi_state_res_mode_t;
|
|||||||
|
|
||||||
#define CGI_STATE_PENDING_IO_THRESHOLD 5
|
#define CGI_STATE_PENDING_IO_THRESHOLD 5
|
||||||
|
|
||||||
|
#define CGI_STATE_OVER_READ_FROM_CLIENT (1 << 0)
|
||||||
|
#define CGI_STATE_OVER_READ_FROM_PEER (1 << 1)
|
||||||
|
#define CGI_STATE_OVER_WRITE_TO_CLIENT (1 << 2)
|
||||||
|
#define CGI_STATE_OVER_WRITE_TO_PEER (1 << 3)
|
||||||
|
#define CGI_STATE_OVER_ALL (CGI_STATE_OVER_READ_FROM_CLIENT | CGI_STATE_OVER_READ_FROM_PEER | CGI_STATE_OVER_WRITE_TO_CLIENT | CGI_STATE_OVER_WRITE_TO_PEER)
|
||||||
|
|
||||||
|
|
||||||
struct cgi_state_t
|
struct cgi_state_t
|
||||||
{
|
{
|
||||||
MIO_SVC_HTTS_RSRC_HEADER;
|
MIO_SVC_HTTS_RSRC_HEADER;
|
||||||
@ -624,16 +635,17 @@ struct cgi_state_t
|
|||||||
mio_oow_t num_pending_writes_to_peer;
|
mio_oow_t num_pending_writes_to_peer;
|
||||||
mio_dev_pro_t* peer;
|
mio_dev_pro_t* peer;
|
||||||
mio_htrd_t* peer_htrd;
|
mio_htrd_t* peer_htrd;
|
||||||
mio_svc_htts_cli_t* cli;
|
mio_svc_htts_cli_t* client;
|
||||||
mio_http_version_t req_version; /* client request */
|
mio_http_version_t req_version; /* client request */
|
||||||
|
|
||||||
|
unsigned int over: 4; /* must be large enough to accomodate CGI_STATE_OVER_ALL */
|
||||||
|
unsigned int keep_alive: 1;
|
||||||
unsigned int req_content_length_unlimited: 1;
|
unsigned int req_content_length_unlimited: 1;
|
||||||
unsigned int peer_eof: 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 cli_org_on_read;
|
mio_dev_sck_on_read_t client_org_on_read;
|
||||||
mio_dev_sck_on_write_t cli_org_on_write;
|
mio_dev_sck_on_write_t client_org_on_write;
|
||||||
};
|
};
|
||||||
typedef struct cgi_state_t cgi_state_t;
|
typedef struct cgi_state_t cgi_state_t;
|
||||||
|
|
||||||
@ -645,12 +657,12 @@ typedef struct cgi_peer_xtn_t cgi_peer_xtn_t;
|
|||||||
|
|
||||||
static void cgi_state_halt_participating_devices (cgi_state_t* cgi_state)
|
static void cgi_state_halt_participating_devices (cgi_state_t* cgi_state)
|
||||||
{
|
{
|
||||||
MIO_ASSERT (cgi_state->cli->htts->mio, cgi_state->cli != MIO_NULL);
|
MIO_ASSERT (cgi_state->client->htts->mio, cgi_state->client != MIO_NULL);
|
||||||
MIO_ASSERT (cgi_state->cli->htts->mio, cgi_state->cli->sck != MIO_NULL);
|
MIO_ASSERT (cgi_state->client->htts->mio, cgi_state->client->sck != MIO_NULL);
|
||||||
|
|
||||||
MIO_DEBUG4 (cgi_state->cli->htts->mio, "HTTS(%p) - halting cgi state %p(client=%p,peer=%p)\n", cgi_state->cli->htts, cgi_state, cgi_state->cli->sck, cgi_state->peer);
|
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_dev_sck_halt (cgi_state->cli->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);
|
||||||
|
|
||||||
@ -660,8 +672,9 @@ static void cgi_state_halt_participating_devices (cgi_state_t* 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)
|
||||||
{
|
{
|
||||||
|
printf ("WRIING TO CLIENT %d\n", dlen);
|
||||||
cgi_state->num_pending_writes_to_client++;
|
cgi_state->num_pending_writes_to_client++;
|
||||||
if (mio_dev_sck_write(cgi_state->cli->sck, data, dlen, MIO_NULL, MIO_NULL) <= -1)
|
if (mio_dev_sck_write(cgi_state->client->sck, data, dlen, MIO_NULL, MIO_NULL) <= -1)
|
||||||
{
|
{
|
||||||
cgi_state->num_pending_writes_to_client--;
|
cgi_state->num_pending_writes_to_client--;
|
||||||
return -1;
|
return -1;
|
||||||
@ -676,8 +689,9 @@ static int cgi_state_write_to_client (cgi_state_t* cgi_state, const void* data,
|
|||||||
|
|
||||||
static int cgi_state_writev_to_client (cgi_state_t* cgi_state, mio_iovec_t* iov, mio_iolen_t iovcnt)
|
static int cgi_state_writev_to_client (cgi_state_t* cgi_state, mio_iovec_t* iov, mio_iolen_t iovcnt)
|
||||||
{
|
{
|
||||||
|
printf ("WRITIV TO CLIENT iovcnt = %d\n", (int)iovcnt);
|
||||||
cgi_state->num_pending_writes_to_client++;
|
cgi_state->num_pending_writes_to_client++;
|
||||||
if (mio_dev_sck_writev(cgi_state->cli->sck, iov, iovcnt, MIO_NULL, MIO_NULL) <= -1)
|
if (mio_dev_sck_writev(cgi_state->client->sck, iov, iovcnt, MIO_NULL, MIO_NULL) <= -1)
|
||||||
{
|
{
|
||||||
cgi_state->num_pending_writes_to_client--;
|
cgi_state->num_pending_writes_to_client--;
|
||||||
return -1;
|
return -1;
|
||||||
@ -692,6 +706,7 @@ static int cgi_state_writev_to_client (cgi_state_t* cgi_state, mio_iovec_t* iov,
|
|||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
printf ("WRIING TO PEER %d\n", (int)dlen);
|
||||||
cgi_state->num_pending_writes_to_peer++;
|
cgi_state->num_pending_writes_to_peer++;
|
||||||
if (mio_dev_pro_write(cgi_state->peer, data, dlen, MIO_NULL) <= -1)
|
if (mio_dev_pro_write(cgi_state->peer, data, dlen, MIO_NULL) <= -1)
|
||||||
{
|
{
|
||||||
@ -702,14 +717,14 @@ static int cgi_state_write_to_peer (cgi_state_t* cgi_state, const void* data, mi
|
|||||||
/* TODO: check if it's already finished or something.. */
|
/* TODO: check if it's already finished or something.. */
|
||||||
if (cgi_state->num_pending_writes_to_peer > CGI_STATE_PENDING_IO_THRESHOLD)
|
if (cgi_state->num_pending_writes_to_peer > CGI_STATE_PENDING_IO_THRESHOLD)
|
||||||
{
|
{
|
||||||
if (mio_dev_sck_read(cgi_state->cli->sck, 0) <= -1) return -1;
|
if (mio_dev_sck_read(cgi_state->client->sck, 0) <= -1) return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cgi_state_send_final_status_to_client (cgi_state_t* cgi_state, int status_code)
|
static int cgi_state_send_final_status_to_client (cgi_state_t* cgi_state, int status_code)
|
||||||
{
|
{
|
||||||
mio_svc_htts_cli_t* cli = cgi_state->cli;
|
mio_svc_htts_cli_t* cli = cgi_state->client;
|
||||||
mio_bch_t dtbuf[64];
|
mio_bch_t dtbuf[64];
|
||||||
|
|
||||||
mio_svc_htts_fmtgmtime (cli->htts, MIO_NULL, dtbuf, MIO_COUNTOF(dtbuf));
|
mio_svc_htts_fmtgmtime (cli->htts, MIO_NULL, dtbuf, MIO_COUNTOF(dtbuf));
|
||||||
@ -722,6 +737,42 @@ static int cgi_state_send_final_status_to_client (cgi_state_t* cgi_state, int st
|
|||||||
return cgi_state_write_to_client(cgi_state, MIO_BECS_PTR(cli->sbuf), MIO_BECS_LEN(cli->sbuf));
|
return cgi_state_write_to_client(cgi_state, MIO_BECS_PTR(cli->sbuf), MIO_BECS_LEN(cli->sbuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MIO_INLINE void cgi_state_mark_over (cgi_state_t* cgi_state, int over_bits)
|
||||||
|
{
|
||||||
|
cgi_state->over |= over_bits;
|
||||||
|
|
||||||
|
MIO_DEBUG5 (cgi_state->htts->mio, "HTTS(%p) - client=%p peer=%p new-bits=%x over=%x\n", cgi_state->htts, cgi_state->client->sck, cgi_state->peer, (int)over_bits, (int)cgi_state->over);
|
||||||
|
|
||||||
|
|
||||||
|
if (cgi_state->over & CGI_STATE_OVER_READ_FROM_CLIENT)
|
||||||
|
{
|
||||||
|
mio_dev_sck_read (cgi_state->client->sck, 0); /* TODO: error handling */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (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->over == CGI_STATE_OVER_ALL)
|
||||||
|
{
|
||||||
|
/* ready to stop */
|
||||||
|
if (cgi_state->peer) mio_dev_pro_halt (cgi_state->peer);
|
||||||
|
|
||||||
|
if (cgi_state->keep_alive)
|
||||||
|
{
|
||||||
|
/* how to arrange to delete this cgi_state object and put the socket back to the normal waiting state??? */
|
||||||
|
printf ("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mio_dev_sck_shutdown (cgi_state->client->sck, MIO_DEV_SCK_SHUTDOWN_WRITE);
|
||||||
|
mio_dev_sck_halt (cgi_state->client->sck);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void cgi_state_on_kill (cgi_state_t* cgi_state)
|
static void cgi_state_on_kill (cgi_state_t* cgi_state)
|
||||||
{
|
{
|
||||||
printf ("**** CGI_STATE_ON_KILL \n");
|
printf ("**** CGI_STATE_ON_KILL \n");
|
||||||
@ -743,19 +794,19 @@ printf ("**** CGI_STATE_ON_KILL \n");
|
|||||||
cgi_state->peer_htrd = MIO_NULL;
|
cgi_state->peer_htrd = MIO_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cgi_state->cli_org_on_read)
|
if (cgi_state->client_org_on_read)
|
||||||
{
|
{
|
||||||
cgi_state->cli->sck->on_read = cgi_state->cli_org_on_read;
|
cgi_state->client->sck->on_read = cgi_state->client_org_on_read;
|
||||||
cgi_state->cli_org_on_read = MIO_NULL;
|
cgi_state->client_org_on_read = MIO_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cgi_state->cli_org_on_write)
|
if (cgi_state->client_org_on_write)
|
||||||
{
|
{
|
||||||
cgi_state->cli->sck->on_write = cgi_state->cli_org_on_write;
|
cgi_state->client->sck->on_write = cgi_state->client_org_on_write;
|
||||||
cgi_state->cli_org_on_write = MIO_NULL;
|
cgi_state->client_org_on_write = MIO_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
mio_htrd_setrecbs (cgi_state->cli->htrd, &client_htrd_recbs); /* restore the callbacks */
|
mio_htrd_setrecbs (cgi_state->client->htrd, &client_htrd_recbs); /* restore the callbacks */
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
@ -766,32 +817,39 @@ static void cgi_peer_on_close (mio_dev_pro_t* pro, mio_dev_pro_sid_t sid)
|
|||||||
|
|
||||||
if (!cgi_state) return; /* cgi state already gone */
|
if (!cgi_state) return; /* cgi state already gone */
|
||||||
|
|
||||||
printf (">>>>>>>>> PEER ON CLOSE sid=%d\n", (int)sid);
|
switch (sid)
|
||||||
printf (">> cgi_state %p\n", cgi_state);
|
|
||||||
printf (">> cgi_state->peer %p\n", cgi_state->peer);
|
|
||||||
printf (">> cgi_state->cli %p\n", cgi_state->cli);
|
|
||||||
printf (">> cgi_state->cli->htts %p\n", cgi_state->cli->htts);
|
|
||||||
|
|
||||||
if (sid == MIO_DEV_PRO_MASTER)
|
|
||||||
{
|
{
|
||||||
MIO_DEBUG3 (mio, "HTTS(%p) - peer %p(pid=%d) closing master\n", cgi_state->cli->htts, pro, (int)pro->child_pid);
|
case MIO_DEV_PRO_MASTER:
|
||||||
cgi_peer->state->peer = MIO_NULL; /* clear this peer from the state */
|
MIO_DEBUG3 (mio, "HTTS(%p) - peer %p(pid=%d) closing master\n", cgi_state->client->htts, pro, (int)pro->child_pid);
|
||||||
}
|
cgi_peer->state->peer = MIO_NULL; /* clear this peer from the state */
|
||||||
else
|
break;
|
||||||
{
|
|
||||||
MIO_ASSERT (mio, cgi_state->peer == pro);
|
|
||||||
|
|
||||||
MIO_DEBUG4 (mio, "HTTS(%p) - peer %p(pid=%d) closing slave[%d]\n", cgi_state->cli->htts, pro, (int)pro->child_pid, sid);
|
case MIO_DEV_PRO_OUT:
|
||||||
if (sid == MIO_DEV_PRO_OUT && !cgi_state->peer_eof)
|
MIO_ASSERT (mio, cgi_state->peer == pro);
|
||||||
{
|
MIO_DEBUG4 (mio, "HTTS(%p) - peer %p(pid=%d) closing slave[%d]\n", cgi_state->client->htts, pro, (int)pro->child_pid, sid);
|
||||||
/* check if it's sending... */
|
|
||||||
cgi_state->peer_eof = 1;
|
if (!(cgi_state->over & CGI_STATE_OVER_READ_FROM_PEER))
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
cgi_state_halt_participating_devices (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)
|
||||||
|
{
|
||||||
|
cgi_state_halt_participating_devices (cgi_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
cgi_state_mark_over (cgi_state, CGI_STATE_OVER_READ_FROM_PEER);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MIO_DEV_PRO_IN:
|
||||||
|
cgi_state_mark_over (cgi_state, CGI_STATE_OVER_WRITE_TO_PEER);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MIO_DEV_PRO_ERR:
|
||||||
|
default:
|
||||||
|
MIO_DEBUG4 (mio, "HTTS(%p) - peer %p(pid=%d) closing slave[%d]\n", cgi_state->client->htts, pro, (int)pro->child_pid, sid);
|
||||||
|
/* do nothing */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -806,35 +864,40 @@ static int cgi_peer_on_read (mio_dev_pro_t* pro, mio_dev_pro_sid_t sid, const vo
|
|||||||
printf (">>>>>>>>> PEER ON READ %d\n", dlen);
|
printf (">>>>>>>>> PEER ON READ %d\n", dlen);
|
||||||
if (dlen <= -1)
|
if (dlen <= -1)
|
||||||
{
|
{
|
||||||
MIO_DEBUG3 (mio, "HTTPS(%p) - read error from peer %p(pid=%u)\n", cgi_state->cli->htts, pro, (unsigned int)pro->child_pid);
|
MIO_DEBUG3 (mio, "HTTPS(%p) - read error from peer %p(pid=%u)\n", cgi_state->client->htts, pro, (unsigned int)pro->child_pid);
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cgi_state->peer_eof) return 0; /* will ignore */
|
#if 0
|
||||||
|
if (cgi_state->over & CGI_STATE_OVER_READ_FROM_PEER) return 0; /* ignore the read event */
|
||||||
|
#endif
|
||||||
|
|
||||||
if (dlen == 0)
|
if (dlen == 0)
|
||||||
{
|
{
|
||||||
MIO_DEBUG3 (mio, "HTTPS(%p) - EOF from peer %p(pid=%u)\n", cgi_state->cli->htts, pro, (unsigned int)pro->child_pid);
|
MIO_DEBUG3 (mio, "HTTPS(%p) - EOF from peer %p(pid=%u)\n", cgi_state->client->htts, pro, (unsigned int)pro->child_pid);
|
||||||
cgi_state->peer_eof = 1;
|
|
||||||
|
|
||||||
if (cgi_state->res_mode_to_cli == CGI_STATE_RES_MODE_CHUNKED &&
|
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_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);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mio_oow_t rem;
|
mio_oow_t rem;
|
||||||
printf ( "QQQQQQQQQQQQQQQQQQ>>>>>>>>>>>>>>>>>> feeding to peer htrd.... dlen => %d\n", (int)dlen);
|
|
||||||
if (mio_htrd_feed(cgi_state->peer_htrd, data, dlen, &rem) <= -1)
|
if (mio_htrd_feed(cgi_state->peer_htrd, data, dlen, &rem) <= -1)
|
||||||
{
|
{
|
||||||
printf ( "FEEDING FAILURE TO PEER HTDDRD.. dlen => %d\n", (int)dlen);
|
printf ( "FEEDING FAILURE TO PEER HTDDRD.. dlen => %d\n", (int)dlen);
|
||||||
cgi_state_send_final_status_to_client (cgi_state, 500); /* don't care about error */
|
cgi_state_send_final_status_to_client (cgi_state, 500); /* don't care about error */
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rem > 0)
|
if (rem > 0)
|
||||||
{
|
{
|
||||||
/* If the script specifies Content-Length and produces longer data, it will come here */
|
/* If the script specifies Content-Length and produces longer data, it will come here */
|
||||||
printf ("AAAAAAAAAAAAAAAAAa EEEEEXcessive DATA..................\n");
|
printf ("AAAAAAAAAAAAAAAAAa EEEEEXcessive DATA..................\n");
|
||||||
cgi_state->peer_eof = 1; /* EOF or use another bit-field? */
|
/* TODO: or drop this request?? */
|
||||||
|
cgi_state_mark_over (cgi_state, CGI_STATE_OVER_READ_FROM_PEER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -873,11 +936,12 @@ static int cgi_peer_capture_header (mio_htre_t* req, const mio_bch_t* key, const
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cgi_peer_htrd_peek (mio_htrd_t* htrd, mio_htre_t* req)
|
static int cgi_peer_htrd_peek (mio_htrd_t* htrd, mio_htre_t* req)
|
||||||
{
|
{
|
||||||
cgi_peer_xtn_t* cgi_peer = mio_htrd_getxtn(htrd);
|
cgi_peer_xtn_t* cgi_peer = mio_htrd_getxtn(htrd);
|
||||||
cgi_state_t* cgi_state = cgi_peer->state;
|
cgi_state_t* cgi_state = cgi_peer->state;
|
||||||
mio_svc_htts_cli_t* cli = cgi_state->cli;
|
mio_svc_htts_cli_t* cli = cgi_state->client;
|
||||||
mio_bch_t dtbuf[64];
|
mio_bch_t dtbuf[64];
|
||||||
int status_code;
|
int status_code;
|
||||||
|
|
||||||
@ -942,7 +1006,7 @@ static int cgi_peer_htrd_push_content (mio_htrd_t* htrd, mio_htre_t* req, const
|
|||||||
cgi_peer_xtn_t* cgi_peer = mio_htrd_getxtn(htrd);
|
cgi_peer_xtn_t* cgi_peer = mio_htrd_getxtn(htrd);
|
||||||
cgi_state_t* cgi_state = cgi_peer->state;
|
cgi_state_t* cgi_state = cgi_peer->state;
|
||||||
|
|
||||||
MIO_ASSERT (cgi_state->cli->htts->mio, htrd == cgi_state->peer_htrd);
|
MIO_ASSERT (cgi_state->client->htts->mio, htrd == cgi_state->peer_htrd);
|
||||||
|
|
||||||
switch (cgi_state->res_mode_to_cli)
|
switch (cgi_state->res_mode_to_cli)
|
||||||
{
|
{
|
||||||
@ -958,7 +1022,7 @@ static int cgi_peer_htrd_push_content (mio_htrd_t* htrd, mio_htre_t* req, const
|
|||||||
|
|
||||||
iov[0].iov_ptr = lbuf;
|
iov[0].iov_ptr = lbuf;
|
||||||
iov[0].iov_len = llen;
|
iov[0].iov_len = llen;
|
||||||
iov[1].iov_ptr = data;
|
iov[1].iov_ptr = (void*)data;
|
||||||
iov[1].iov_len = dlen;
|
iov[1].iov_len = dlen;
|
||||||
iov[2].iov_ptr = "\r\n";
|
iov[2].iov_ptr = "\r\n";
|
||||||
iov[2].iov_len = 2;
|
iov[2].iov_len = 2;
|
||||||
@ -991,15 +1055,33 @@ static mio_htrd_recbs_t cgi_peer_htrd_recbs =
|
|||||||
cgi_peer_htrd_push_content
|
cgi_peer_htrd_push_content
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int walk_client_req_trailer (mio_htre_t* req, const mio_bch_t* key, const mio_htre_hdrval_t* val, void* ctx)
|
||||||
|
{
|
||||||
|
printf ("\t%s=");
|
||||||
|
while (val)
|
||||||
|
{
|
||||||
|
printf ("%s ", val->ptr);
|
||||||
|
val = val->next;
|
||||||
|
}
|
||||||
|
printf ("\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int cgi_client_htrd_poke (mio_htrd_t* htrd, mio_htre_t* req)
|
static int cgi_client_htrd_poke (mio_htrd_t* htrd, mio_htre_t* req)
|
||||||
{
|
{
|
||||||
/* client request got completed */
|
/* client request got completed */
|
||||||
htrd_xtn_t* htrdxtn = mio_htrd_getxtn(htrd);
|
htrd_xtn_t* htrdxtn = mio_htrd_getxtn(htrd);
|
||||||
mio_dev_sck_t* sck = htrdxtn->sck;
|
mio_dev_sck_t* sck = htrdxtn->sck;
|
||||||
mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(sck);
|
mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(sck);
|
||||||
cgi_state_t* cgi_state = cli->rsrc;
|
cgi_state_t* cgi_state = (cgi_state_t*)cli->rsrc;
|
||||||
|
|
||||||
|
|
||||||
|
printf (">> CLIENT REQUEST COMPLETED\n");
|
||||||
|
//mio_htre_walkheaders (req, walk_client_req_trailer, MIO_NULL);
|
||||||
|
mio_htre_walktrailers (req, walk_client_req_trailer, MIO_NULL); // MIO_HTRD_TRAILERS must be set for this to work
|
||||||
|
|
||||||
/* indicate EOF to the client peer */
|
/* indicate EOF to the client peer */
|
||||||
|
cgi_state_mark_over (cgi_state, CGI_STATE_OVER_READ_FROM_CLIENT);
|
||||||
return cgi_state_write_to_peer(cgi_state, MIO_NULL, 0);
|
return cgi_state_write_to_peer(cgi_state, MIO_NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1008,7 +1090,7 @@ static int cgi_client_htrd_push_content (mio_htrd_t* htrd, mio_htre_t* req, cons
|
|||||||
htrd_xtn_t* htrdxtn = mio_htrd_getxtn(htrd);
|
htrd_xtn_t* htrdxtn = mio_htrd_getxtn(htrd);
|
||||||
mio_dev_sck_t* sck = htrdxtn->sck;
|
mio_dev_sck_t* sck = htrdxtn->sck;
|
||||||
mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(sck);
|
mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(sck);
|
||||||
cgi_state_t* cgi_state = cli->rsrc;
|
cgi_state_t* cgi_state = (cgi_state_t*)cli->rsrc;
|
||||||
|
|
||||||
MIO_ASSERT (sck->mio, cli->sck == sck);
|
MIO_ASSERT (sck->mio, cli->sck == sck);
|
||||||
return cgi_state_write_to_peer(cgi_state, data, dlen);
|
return cgi_state_write_to_peer(cgi_state, data, dlen);
|
||||||
@ -1024,18 +1106,20 @@ static int cgi_peer_on_write (mio_dev_pro_t* pro, mio_iolen_t wrlen, void* wrctx
|
|||||||
|
|
||||||
if (wrlen <= -1)
|
if (wrlen <= -1)
|
||||||
{
|
{
|
||||||
MIO_DEBUG3 (mio, "HTTS(%p) - unable to write to peer %p(pid=%u)\n", cgi_state->cli->htts, pro, (int)pro->child_pid);
|
MIO_DEBUG3 (mio, "HTTS(%p) - unable to write to peer %p(pid=%u)\n", cgi_state->client->htts, pro, (int)pro->child_pid);
|
||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
else if (wrlen == 0)
|
else if (wrlen == 0)
|
||||||
{
|
{
|
||||||
/* indicated EOF */
|
/* indicated EOF */
|
||||||
/* do nothing here as i didn't incremented num_pending_writes_to_peer when making the write request */
|
/* do nothing here as i didn't incremented num_pending_writes_to_peer when making the write request */
|
||||||
|
|
||||||
cgi_state->num_pending_writes_to_peer--;
|
cgi_state->num_pending_writes_to_peer--;
|
||||||
MIO_ASSERT (mio, cgi_state->num_pending_writes_to_peer == 0);
|
MIO_ASSERT (mio, cgi_state->num_pending_writes_to_peer == 0);
|
||||||
MIO_DEBUG3 (mio, "HTTS(%p) - indicated EOF to peer %p(pid=%u)\n", cgi_state->cli->htts, pro, (int)pro->child_pid);
|
MIO_DEBUG3 (mio, "HTTS(%p) - indicated EOF to peer %p(pid=%u)\n", cgi_state->client->htts, pro, (int)pro->child_pid);
|
||||||
/* indicated EOF to the peer side. i need no more data from the client side.
|
/* indicated EOF to the peer side. i need no more data from the client side.
|
||||||
* i don't need to enable input watching in the client side either */
|
* i don't need to enable input watching in the client side either */
|
||||||
|
cgi_state_mark_over (cgi_state, CGI_STATE_OVER_WRITE_TO_PEER);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1044,8 +1128,13 @@ static int cgi_peer_on_write (mio_dev_pro_t* pro, mio_iolen_t wrlen, void* wrctx
|
|||||||
cgi_state->num_pending_writes_to_peer--;
|
cgi_state->num_pending_writes_to_peer--;
|
||||||
if (cgi_state->num_pending_writes_to_peer == CGI_STATE_PENDING_IO_THRESHOLD)
|
if (cgi_state->num_pending_writes_to_peer == CGI_STATE_PENDING_IO_THRESHOLD)
|
||||||
{
|
{
|
||||||
// TODO: check if (cli has anything to read...) if so ...
|
if (!(cgi_state->over & CGI_STATE_OVER_READ_FROM_CLIENT) &&
|
||||||
if (mio_dev_sck_read(cgi_state->cli->sck, 1) <= -1) goto oops;
|
mio_dev_sck_read(cgi_state->client->sck, 1) <= -1) goto oops;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((cgi_state->over & CGI_STATE_OVER_READ_FROM_CLIENT) && cgi_state->num_pending_writes_to_peer <= 0)
|
||||||
|
{
|
||||||
|
cgi_state_mark_over (cgi_state, CGI_STATE_OVER_WRITE_TO_PEER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1056,12 +1145,11 @@ oops:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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;
|
||||||
mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(sck);
|
mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(sck);
|
||||||
cgi_state_t* cgi_state = cli->rsrc;
|
cgi_state_t* cgi_state = (cgi_state_t*)cli->rsrc;
|
||||||
|
|
||||||
MIO_ASSERT (mio, sck == cli->sck);
|
MIO_ASSERT (mio, sck == cli->sck);
|
||||||
|
|
||||||
@ -1083,24 +1171,16 @@ printf ("** HTTS - cgi client read %p %d -> htts:%p\n", sck, (int)len, cli->h
|
|||||||
if (len == 0)
|
if (len == 0)
|
||||||
{
|
{
|
||||||
/* EOF on the client side. arrange to close */
|
/* EOF on the client side. arrange to close */
|
||||||
printf ("asking pro to close...\n");
|
|
||||||
/* HAVE I ALREADY CLOSED IT??? Check conflict is the poke handler */
|
|
||||||
return cgi_state_write_to_peer(cgi_state, MIO_NULL, 0);
|
return cgi_state_write_to_peer(cgi_state, MIO_NULL, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mio_oow_t rem;
|
mio_oow_t rem;
|
||||||
/* EOF if it got content as long as cgi_state->req_content_length??? */
|
if (mio_htrd_feed(cli->htrd, buf, len, &rem) <= -1) goto oops;
|
||||||
if (mio_htrd_feed(cli->htrd, buf, len, &rem) <= -1)
|
|
||||||
{
|
|
||||||
printf ("FAILED TO FEED TH CLIENT HTRD......\n");
|
|
||||||
goto oops;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rem > 0)
|
if (rem > 0)
|
||||||
{
|
{
|
||||||
/* the cgi script is not behaving properly */
|
printf ("UUUUUUUUUUUUUUUUUUUUUUUUUUGGGGGHHHHHHHHHHHH .......... CGI CLIENT GIVING EXCESSIVE DATA AFTER CONTENTS...\n");
|
||||||
/* giving excessive data... */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1116,7 +1196,7 @@ static int cgi_client_on_write (mio_dev_sck_t* sck, mio_iolen_t wrlen, void* wrc
|
|||||||
{
|
{
|
||||||
mio_t* mio = sck->mio;
|
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);
|
||||||
cgi_state_t* cgi_state = cli->rsrc;
|
cgi_state_t* cgi_state = (cgi_state_t*)cli->rsrc;
|
||||||
|
|
||||||
if (wrlen <= -1)
|
if (wrlen <= -1)
|
||||||
{
|
{
|
||||||
@ -1129,29 +1209,26 @@ static int cgi_client_on_write (mio_dev_sck_t* sck, mio_iolen_t wrlen, void* wrc
|
|||||||
/* if the connect is keep-alive, this part may not be called */
|
/* if the connect is keep-alive, this part may not be called */
|
||||||
cgi_state->num_pending_writes_to_client--;
|
cgi_state->num_pending_writes_to_client--;
|
||||||
MIO_ASSERT (mio, cgi_state->num_pending_writes_to_client == 0);
|
MIO_ASSERT (mio, cgi_state->num_pending_writes_to_client == 0);
|
||||||
MIO_DEBUG3 (mio, "HTTS(%p) - indicated EOF to client %p(%d)\n", cgi_state->cli->htts, sck, (int)sck->hnd);
|
MIO_DEBUG3 (mio, "HTTS(%p) - indicated EOF to client %p(%d)\n", cgi_state->client->htts, sck, (int)sck->hnd);
|
||||||
/* since EOF has been indicated to the client, it must not write to the client any further.
|
/* since EOF has been indicated to the client, it must not write to the client any further.
|
||||||
* this also means that i don't need any data from the peer side either.
|
* this also means that i don't need any data from the peer side either.
|
||||||
* i don't need to enable input watching on the peer side */
|
* i don't need to enable input watching on the peer side */
|
||||||
|
cgi_state_mark_over (cgi_state, CGI_STATE_OVER_WRITE_TO_CLIENT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MIO_ASSERT (mio, cgi_state->num_pending_writes_to_client > 0);
|
MIO_ASSERT (mio, cgi_state->num_pending_writes_to_client > 0);
|
||||||
|
|
||||||
printf ("MANAGED TO WRITE TO CLIENT>... %d\n", (int)wrlen);
|
|
||||||
cgi_state->num_pending_writes_to_client--;
|
cgi_state->num_pending_writes_to_client--;
|
||||||
if (cgi_state->peer && cgi_state->num_pending_writes_to_client == CGI_STATE_PENDING_IO_THRESHOLD)
|
if (cgi_state->peer && cgi_state->num_pending_writes_to_client == CGI_STATE_PENDING_IO_THRESHOLD)
|
||||||
{
|
{
|
||||||
// TODO: check if there is anything to read... */
|
if (!(cgi_state->over & CGI_STATE_OVER_READ_FROM_PEER) &&
|
||||||
if (mio_dev_pro_read(cgi_state->peer, MIO_DEV_PRO_OUT, 1) <= -1) goto oops;
|
mio_dev_pro_read(cgi_state->peer, MIO_DEV_PRO_OUT, 1) <= -1) goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* in case the peer died before peer read handler reads EOF */
|
if ((cgi_state->over & CGI_STATE_OVER_READ_FROM_PEER) && cgi_state->num_pending_writes_to_client <= 0)
|
||||||
if (cgi_state->peer_eof && cgi_state->num_pending_writes_to_client <= 0)
|
|
||||||
{
|
{
|
||||||
/*if (no_more_input is to be read from the client)*/
|
cgi_state_mark_over (cgi_state, CGI_STATE_OVER_WRITE_TO_CLIENT);
|
||||||
cgi_state_halt_participating_devices (cgi_state); // must not use this... must kill the state ...
|
|
||||||
/* finished writing all */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1194,7 +1271,6 @@ 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;
|
||||||
int enable_input;
|
|
||||||
|
|
||||||
/* 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);
|
||||||
@ -1209,14 +1285,14 @@ int mio_svc_htts_docgi (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* r
|
|||||||
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;
|
||||||
|
|
||||||
cgi_state->cli = cli;
|
cgi_state->client = cli;
|
||||||
/*cgi_state->num_pending_writes_to_client = 0;
|
/*cgi_state->num_pending_writes_to_client = 0;
|
||||||
cgi_state->num_pending_writes_to_peer = 0;*/
|
cgi_state->num_pending_writes_to_peer = 0;*/
|
||||||
cgi_state->req_version = *mio_htre_getversion(req);
|
cgi_state->req_version = *mio_htre_getversion(req);
|
||||||
cgi_state->req_content_length_unlimited = get_request_content_length(req, &cgi_state->req_content_length);
|
cgi_state->req_content_length_unlimited = get_request_content_length(req, &cgi_state->req_content_length);
|
||||||
|
|
||||||
cgi_state->cli_org_on_read = csck->on_read;
|
cgi_state->client_org_on_read = csck->on_read;
|
||||||
cgi_state->cli_org_on_write = csck->on_write;
|
cgi_state->client_org_on_write = csck->on_write;
|
||||||
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;
|
||||||
|
|
||||||
@ -1287,7 +1363,6 @@ int mio_svc_htts_docgi (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* r
|
|||||||
goto oops;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
enable_input = 1;
|
|
||||||
#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)
|
||||||
{
|
{
|
||||||
@ -1299,8 +1374,8 @@ int mio_svc_htts_docgi (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* r
|
|||||||
|
|
||||||
/* TODO: must set CONTENT-LENGTH to -1 before start the process */
|
/* TODO: must set CONTENT-LENGTH to -1 before start the process */
|
||||||
/* change the callbacks to subscribe to contents to be uploaded */
|
/* change the callbacks to subscribe to contents to be uploaded */
|
||||||
cgi_state->cli->htrd->recbs.poke = cgi_client_htrd_poke;
|
cgi_state->client->htrd->recbs.poke = cgi_client_htrd_poke;
|
||||||
cgi_state->cli->htrd->recbs.push_content = cgi_client_htrd_push_content;
|
cgi_state->client->htrd->recbs.push_content = cgi_client_htrd_push_content;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1309,26 +1384,36 @@ int mio_svc_htts_docgi (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* r
|
|||||||
{
|
{
|
||||||
|
|
||||||
/* change the callbacks to subscribe to contents to be uploaded */
|
/* change the callbacks to subscribe to contents to be uploaded */
|
||||||
cgi_state->cli->htrd->recbs.poke = cgi_client_htrd_poke;
|
cgi_state->client->htrd->recbs.poke = cgi_client_htrd_poke;
|
||||||
cgi_state->cli->htrd->recbs.push_content = cgi_client_htrd_push_content;
|
cgi_state->client->htrd->recbs.push_content = cgi_client_htrd_push_content;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* no content to be uploaded from the client */
|
/* no content to be uploaded from the client */
|
||||||
/* indicate EOF to the peer and disable input wathching from the client */
|
/* indicate EOF to the peer and disable input wathching from the client */
|
||||||
if (cgi_state_write_to_peer(cgi_state, MIO_NULL, 0) <= -1) goto oops;
|
if (cgi_state_write_to_peer(cgi_state, MIO_NULL, 0) <= -1) goto oops;
|
||||||
enable_input = 0;
|
cgi_state_mark_over (cgi_state, CGI_STATE_OVER_READ_FROM_CLIENT | CGI_STATE_OVER_WRITE_TO_PEER);
|
||||||
}
|
}
|
||||||
#if defined(CGI_ALLOW_UNLIMITED_REQ_CONTENT_LENGTH)
|
#if defined(CGI_ALLOW_UNLIMITED_REQ_CONTENT_LENGTH)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* TODO: store current input watching state and use it when destroying the cgi_state data */
|
|
||||||
if (mio_dev_sck_read(csck, enable_input) <= -1) goto oops;
|
|
||||||
|
|
||||||
|
|
||||||
/* this may change later if Content-Length is included in the cgi output */
|
/* this may change later if Content-Length is included in the cgi output */
|
||||||
cgi_state->res_mode_to_cli = (req->flags & MIO_HTRE_ATTR_KEEPALIVE)? CGI_STATE_RES_MODE_CHUNKED: CGI_STATE_RES_MODE_CLOSE;
|
if (req->flags & MIO_HTRE_ATTR_KEEPALIVE)
|
||||||
|
{
|
||||||
|
cgi_state->keep_alive = 1;
|
||||||
|
cgi_state->res_mode_to_cli = CGI_STATE_RES_MODE_CHUNKED;
|
||||||
|
/* the mode still can get switched to CGI_STATE_RES_MODE_LENGTH if the cgi script emits Content-Length */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cgi_state->keep_alive = 0;
|
||||||
|
cgi_state->res_mode_to_cli = CGI_STATE_RES_MODE_CLOSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
oops:
|
oops:
|
||||||
|
@ -409,6 +409,13 @@ struct mio_dev_sck_t
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum mio_dev_sck_shutdown_how_t
|
||||||
|
{
|
||||||
|
MIO_DEV_SCK_SHUTDOWN_READ = (1 << 0),
|
||||||
|
MIO_DEV_SCK_SHUTDOWN_WRITE = (1 << 1)
|
||||||
|
};
|
||||||
|
typedef enum mio_dev_sck_shutdown_how_t mio_dev_sck_shutdown_how_t;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@ -520,7 +527,6 @@ static MIO_INLINE int mio_dev_sck_timedread (mio_dev_sck_t* sck, int enabled, mi
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
MIO_EXPORT int mio_dev_sck_setsockopt (
|
MIO_EXPORT int mio_dev_sck_setsockopt (
|
||||||
mio_dev_sck_t* dev,
|
mio_dev_sck_t* dev,
|
||||||
int level,
|
int level,
|
||||||
@ -537,7 +543,12 @@ MIO_EXPORT int mio_dev_sck_getsockopt (
|
|||||||
mio_scklen_t* optlen
|
mio_scklen_t* optlen
|
||||||
);
|
);
|
||||||
|
|
||||||
MIO_EXPORT mio_uint16_t mio_checksumip (
|
MIO_EXPORT int mio_dev_sck_shutdown (
|
||||||
|
mio_dev_sck_t* dev,
|
||||||
|
int how /* bitwise-ORed of mio_dev_sck_shutdown_how_t enumerators */
|
||||||
|
);
|
||||||
|
|
||||||
|
MIO_EXPORT mio_uint16_t mio_checksum_ip (
|
||||||
const void* hdr,
|
const void* hdr,
|
||||||
mio_oow_t len
|
mio_oow_t len
|
||||||
);
|
);
|
||||||
|
@ -696,7 +696,9 @@ int mio_exec (mio_t* mio)
|
|||||||
|
|
||||||
if (mio_gettmrtmout(mio, MIO_NULL, &tmout) <= -1)
|
if (mio_gettmrtmout(mio, MIO_NULL, &tmout) <= -1)
|
||||||
{
|
{
|
||||||
/* defaults to 1 second if timeout can't be acquired */
|
/* defaults to 1 second if timeout can't be acquired.
|
||||||
|
* if this timeout affects how fast the halted device will get
|
||||||
|
* killed when there are no events or timer jobs */
|
||||||
tmout.sec = 1; /* TODO: make the default timeout configurable */
|
tmout.sec = 1; /* TODO: make the default timeout configurable */
|
||||||
tmout.nsec = 0;
|
tmout.nsec = 0;
|
||||||
}
|
}
|
||||||
|
@ -546,6 +546,12 @@ static int dev_pro_read_slave (mio_dev_t* dev, void* buf, mio_iolen_t* len, mio_
|
|||||||
mio_dev_pro_slave_t* pro = (mio_dev_pro_slave_t*)dev;
|
mio_dev_pro_slave_t* pro = (mio_dev_pro_slave_t*)dev;
|
||||||
ssize_t x;
|
ssize_t x;
|
||||||
|
|
||||||
|
if (MIO_UNLIKELY(pro->pfd == MIO_SYSHND_INVALID))
|
||||||
|
{
|
||||||
|
mio_seterrnum (pro->mio, MIO_EBADHND);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
x = read(pro->pfd, buf, *len);
|
x = read(pro->pfd, buf, *len);
|
||||||
if (x <= -1)
|
if (x <= -1)
|
||||||
{
|
{
|
||||||
@ -564,11 +570,22 @@ static int dev_pro_write_slave (mio_dev_t* dev, const void* data, mio_iolen_t* l
|
|||||||
mio_dev_pro_slave_t* pro = (mio_dev_pro_slave_t*)dev;
|
mio_dev_pro_slave_t* pro = (mio_dev_pro_slave_t*)dev;
|
||||||
ssize_t x;
|
ssize_t x;
|
||||||
|
|
||||||
|
if (MIO_UNLIKELY(pro->pfd == MIO_SYSHND_INVALID))
|
||||||
|
{
|
||||||
|
mio_seterrnum (pro->mio, MIO_EBADHND);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (MIO_UNLIKELY(*len <= 0))
|
if (MIO_UNLIKELY(*len <= 0))
|
||||||
{
|
{
|
||||||
/* this is an EOF indicator */
|
/* this is an EOF indicator */
|
||||||
mio_dev_halt (dev); /* halt this slave device */
|
//mio_dev_halt (dev); /* halt this slave device to indicate EOF on the lower-level handle */*
|
||||||
return 1;
|
if (MIO_LIKELY(pro->pfd != MIO_SYSHND_INVALID)) /* halt() doesn't close the pipe immediately. so close the underlying pipe */
|
||||||
|
{
|
||||||
|
close (pro->pfd);
|
||||||
|
pro->pfd = MIO_SYSHND_INVALID;
|
||||||
|
}
|
||||||
|
return 1; /* indicate that the operation got successful. the core will execute on_write() with 0. */
|
||||||
}
|
}
|
||||||
|
|
||||||
x = write(pro->pfd, data, *len);
|
x = write(pro->pfd, data, *len);
|
||||||
@ -589,11 +606,22 @@ static int dev_pro_writev_slave (mio_dev_t* dev, const mio_iovec_t* iov, mio_iol
|
|||||||
mio_dev_pro_slave_t* pro = (mio_dev_pro_slave_t*)dev;
|
mio_dev_pro_slave_t* pro = (mio_dev_pro_slave_t*)dev;
|
||||||
ssize_t x;
|
ssize_t x;
|
||||||
|
|
||||||
|
if (MIO_UNLIKELY(pro->pfd == MIO_SYSHND_INVALID))
|
||||||
|
{
|
||||||
|
mio_seterrnum (pro->mio, MIO_EBADHND);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (MIO_UNLIKELY(*iovcnt <= 0))
|
if (MIO_UNLIKELY(*iovcnt <= 0))
|
||||||
{
|
{
|
||||||
/* this is an EOF indicator */
|
/* this is an EOF indicator */
|
||||||
mio_dev_halt (dev); /* halt this slave device */
|
/*mio_dev_halt (dev);*/ /* halt this slave device to indicate EOF on the lower-level handle */
|
||||||
return 1;
|
if (MIO_LIKELY(pro->pfd != MIO_SYSHND_INVALID)) /* halt() doesn't close the pipe immediately. so close the underlying pipe */
|
||||||
|
{
|
||||||
|
close (pro->pfd);
|
||||||
|
pro->pfd = MIO_SYSHND_INVALID;
|
||||||
|
}
|
||||||
|
return 1; /* indicate that the operation got successful. the core will execute on_write() with 0. */
|
||||||
}
|
}
|
||||||
|
|
||||||
x = writev(pro->pfd, iov, *iovcnt);
|
x = writev(pro->pfd, iov, *iovcnt);
|
||||||
|
@ -1716,14 +1716,37 @@ int mio_dev_sck_getsockopt (mio_dev_sck_t* dev, int level, int optname, void* op
|
|||||||
return getsockopt(dev->hnd, level, optname, optval, optlen);
|
return getsockopt(dev->hnd, level, optname, optval, optlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mio_dev_sck_shutdown (mio_dev_sck_t* dev, int how)
|
||||||
|
{
|
||||||
|
switch (how & (MIO_DEV_SCK_SHUTDOWN_READ | MIO_DEV_SCK_SHUTDOWN_WRITE))
|
||||||
|
{
|
||||||
|
case (MIO_DEV_SCK_SHUTDOWN_READ | MIO_DEV_SCK_SHUTDOWN_WRITE):
|
||||||
|
how = SHUT_RDWR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MIO_DEV_SCK_SHUTDOWN_READ:
|
||||||
|
how = SHUT_RD;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MIO_DEV_SCK_SHUTDOWN_WRITE:
|
||||||
|
how = SHUT_WR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
mio_seterrnum (dev->mio, MIO_EINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return shutdown(dev->hnd, how);
|
||||||
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
|
||||||
mio_uint16_t mio_checksumip (const void* hdr, mio_oow_t len)
|
mio_uint16_t mio_checksum_ip (const void* hdr, mio_oow_t len)
|
||||||
{
|
{
|
||||||
mio_uint32_t sum = 0;
|
mio_uint32_t sum = 0;
|
||||||
mio_uint16_t *ptr = (mio_uint16_t*)hdr;
|
mio_uint16_t *ptr = (mio_uint16_t*)hdr;
|
||||||
|
|
||||||
|
|
||||||
while (len > 1)
|
while (len > 1)
|
||||||
{
|
{
|
||||||
sum += *ptr++;
|
sum += *ptr++;
|
||||||
|
13
mio/t/t1.txt
Normal file
13
mio/t/t1.txt
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
POST /home/hyung-hwan/projects/mio/t/b.sh HTTP/1.1
|
||||||
|
Host: abc.txt
|
||||||
|
Content-Type: text/plain
|
||||||
|
Transfer-Encoding: chunked
|
||||||
|
|
||||||
|
7
|
||||||
|
Mozilla
|
||||||
|
9
|
||||||
|
Developer
|
||||||
|
7
|
||||||
|
Network
|
||||||
|
0
|
||||||
|
|
15
mio/t/t2.txt
Normal file
15
mio/t/t2.txt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
GET /home/hyung-hwan/projects/mio/t/b.sh HTTP/1.1
|
||||||
|
Host: abc.txt
|
||||||
|
Transfer-Encoding: chunked
|
||||||
|
Connection: close
|
||||||
|
Trailer: Content-Type
|
||||||
|
|
||||||
|
7
|
||||||
|
Mozilla
|
||||||
|
9
|
||||||
|
Developer
|
||||||
|
7
|
||||||
|
Network
|
||||||
|
0
|
||||||
|
Content-Type: text/plain
|
||||||
|
|
13
mio/t/t3.txt
Normal file
13
mio/t/t3.txt
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
POST /home/hyung-hwan/projects/mio/t/b.sh HTTP/1.0
|
||||||
|
Host: abc.txt
|
||||||
|
Content-Type: text/plain
|
||||||
|
Transfer-Encoding: chunked
|
||||||
|
|
||||||
|
7
|
||||||
|
Mozilla
|
||||||
|
9
|
||||||
|
Developer
|
||||||
|
7
|
||||||
|
Network
|
||||||
|
0
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user