diff --git a/mio/lib/http-cgi.c b/mio/lib/http-cgi.c index 32328fb..3e08ae9 100644 --- a/mio/lib/http-cgi.c +++ b/mio/lib/http-cgi.c @@ -36,23 +36,23 @@ #define CGI_ALLOW_UNLIMITED_REQ_CONTENT_LENGTH -enum cgi_state_res_mode_t +enum cgi_res_mode_t { - CGI_STATE_RES_MODE_CHUNKED, - CGI_STATE_RES_MODE_CLOSE, - CGI_STATE_RES_MODE_LENGTH + CGI_RES_MODE_CHUNKED, + CGI_RES_MODE_CLOSE, + CGI_RES_MODE_LENGTH }; -typedef enum cgi_state_res_mode_t cgi_state_res_mode_t; +typedef enum cgi_res_mode_t cgi_res_mode_t; -#define CGI_STATE_PENDING_IO_THRESHOLD 5 +#define CGI_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) +#define CGI_OVER_READ_FROM_CLIENT (1 << 0) +#define CGI_OVER_READ_FROM_PEER (1 << 1) +#define CGI_OVER_WRITE_TO_CLIENT (1 << 2) +#define CGI_OVER_WRITE_TO_PEER (1 << 3) +#define CGI_OVER_ALL (CGI_OVER_READ_FROM_CLIENT | CGI_OVER_READ_FROM_PEER | CGI_OVER_WRITE_TO_CLIENT | CGI_OVER_WRITE_TO_PEER) -struct cgi_state_t +struct cgi_t { MIO_SVC_HTTS_RSRC_HEADER; @@ -63,268 +63,268 @@ struct cgi_state_t mio_svc_htts_cli_t* client; mio_http_version_t req_version; /* client request */ - 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_OVER_ALL */ unsigned int keep_alive: 1; unsigned int req_content_length_unlimited: 1; unsigned int ever_attempted_to_write_to_client: 1; unsigned int client_disconnected: 1; unsigned int client_htrd_recbs_changed: 1; mio_oow_t req_content_length; /* client request content length */ - cgi_state_res_mode_t res_mode_to_cli; + cgi_res_mode_t res_mode_to_cli; mio_dev_sck_on_read_t client_org_on_read; mio_dev_sck_on_write_t client_org_on_write; mio_dev_sck_on_disconnect_t client_org_on_disconnect; mio_htrd_recbs_t client_htrd_org_recbs; }; -typedef struct cgi_state_t cgi_state_t; +typedef struct cgi_t cgi_t; struct cgi_peer_xtn_t { - cgi_state_t* state; + cgi_t* state; }; 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_halt_participating_devices (cgi_t* cgi) { - 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->client->htts->mio, cgi->client != MIO_NULL); + MIO_ASSERT (cgi->client->htts->mio, cgi->client->sck != MIO_NULL); - 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_DEBUG4 (cgi->client->htts->mio, "HTTS(%p) - Halting participating devices in cgi state %p(client=%p,peer=%p)\n", cgi->client->htts, cgi, cgi->client->sck, cgi->peer); - mio_dev_sck_halt (cgi_state->client->sck); + mio_dev_sck_halt (cgi->client->sck); /* check for peer as it may not have been started */ - if (cgi_state->peer) mio_dev_pro_halt (cgi_state->peer); + if (cgi->peer) mio_dev_pro_halt (cgi->peer); } -static int cgi_state_write_to_client (cgi_state_t* cgi_state, const void* data, mio_iolen_t dlen) +static int cgi_write_to_client (cgi_t* cgi, const void* data, mio_iolen_t dlen) { - cgi_state->ever_attempted_to_write_to_client = 1; + cgi->ever_attempted_to_write_to_client = 1; - cgi_state->num_pending_writes_to_client++; - if (mio_dev_sck_write(cgi_state->client->sck, data, dlen, MIO_NULL, MIO_NULL) <= -1) + cgi->num_pending_writes_to_client++; + if (mio_dev_sck_write(cgi->client->sck, data, dlen, MIO_NULL, MIO_NULL) <= -1) { - cgi_state->num_pending_writes_to_client--; + cgi->num_pending_writes_to_client--; return -1; } - if (cgi_state->num_pending_writes_to_client > CGI_STATE_PENDING_IO_THRESHOLD) + if (cgi->num_pending_writes_to_client > CGI_PENDING_IO_THRESHOLD) { /* disable reading on the output stream of the peer */ - if (mio_dev_pro_read(cgi_state->peer, MIO_DEV_PRO_OUT, 0) <= -1) return -1; + if (mio_dev_pro_read(cgi->peer, MIO_DEV_PRO_OUT, 0) <= -1) return -1; } return 0; } -static int cgi_state_writev_to_client (cgi_state_t* cgi_state, mio_iovec_t* iov, mio_iolen_t iovcnt) +static int cgi_writev_to_client (cgi_t* cgi, mio_iovec_t* iov, mio_iolen_t iovcnt) { - cgi_state->ever_attempted_to_write_to_client = 1; + cgi->ever_attempted_to_write_to_client = 1; - cgi_state->num_pending_writes_to_client++; - if (mio_dev_sck_writev(cgi_state->client->sck, iov, iovcnt, MIO_NULL, MIO_NULL) <= -1) + cgi->num_pending_writes_to_client++; + if (mio_dev_sck_writev(cgi->client->sck, iov, iovcnt, MIO_NULL, MIO_NULL) <= -1) { - cgi_state->num_pending_writes_to_client--; + cgi->num_pending_writes_to_client--; return -1; } - if (cgi_state->num_pending_writes_to_client > CGI_STATE_PENDING_IO_THRESHOLD) + if (cgi->num_pending_writes_to_client > CGI_PENDING_IO_THRESHOLD) { - if (mio_dev_pro_read(cgi_state->peer, MIO_DEV_PRO_OUT, 0) <= -1) return -1; + if (mio_dev_pro_read(cgi->peer, MIO_DEV_PRO_OUT, 0) <= -1) return -1; } return 0; } -static int cgi_state_send_final_status_to_client (cgi_state_t* cgi_state, int status_code, int force_close) +static int cgi_send_final_status_to_client (cgi_t* cgi, int status_code, int force_close) { - mio_svc_htts_cli_t* cli = cgi_state->client; + mio_svc_htts_cli_t* cli = cgi->client; mio_bch_t dtbuf[64]; mio_svc_htts_fmtgmtime (cli->htts, MIO_NULL, dtbuf, MIO_COUNTOF(dtbuf)); - if (!force_close) force_close = !cgi_state->keep_alive; + if (!force_close) force_close = !cgi->keep_alive; if (mio_becs_fmt(cli->sbuf, "HTTP/%d.%d %d %hs\r\nServer: %hs\r\nDate: %s\r\nConnection: %hs\r\nContent-Length: 0\r\n\r\n", - cgi_state->req_version.major, cgi_state->req_version.minor, + cgi->req_version.major, cgi->req_version.minor, status_code, mio_http_status_to_bcstr(status_code), cli->htts->server_name, dtbuf, (force_close? "close": "keep-alive")) == (mio_oow_t)-1) return -1; - return (cgi_state_write_to_client(cgi_state, MIO_BECS_PTR(cli->sbuf), MIO_BECS_LEN(cli->sbuf)) <= -1 || - (force_close && cgi_state_write_to_client(cgi_state, MIO_NULL, 0) <= -1))? -1: 0; + return (cgi_write_to_client(cgi, MIO_BECS_PTR(cli->sbuf), MIO_BECS_LEN(cli->sbuf)) <= -1 || + (force_close && cgi_write_to_client(cgi, MIO_NULL, 0) <= -1))? -1: 0; } -static int cgi_state_write_last_chunk_to_client (cgi_state_t* cgi_state) +static int cgi_write_last_chunk_to_client (cgi_t* cgi) { - if (!cgi_state->ever_attempted_to_write_to_client) + if (!cgi->ever_attempted_to_write_to_client) { - if (cgi_state_send_final_status_to_client(cgi_state, 500, 0) <= -1) return -1; + if (cgi_send_final_status_to_client(cgi, 500, 0) <= -1) return -1; } else { - 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->res_mode_to_cli == CGI_RES_MODE_CHUNKED && + cgi_write_to_client(cgi, "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; + if (!cgi->keep_alive && cgi_write_to_client(cgi, 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_write_to_peer (cgi_t* cgi, const void* data, mio_iolen_t dlen) { - cgi_state->num_pending_writes_to_peer++; - if (mio_dev_pro_write(cgi_state->peer, data, dlen, MIO_NULL) <= -1) + cgi->num_pending_writes_to_peer++; + if (mio_dev_pro_write(cgi->peer, data, dlen, MIO_NULL) <= -1) { - cgi_state->num_pending_writes_to_peer--; + cgi->num_pending_writes_to_peer--; return -1; } /* TODO: check if it's already finished or something.. */ - if (cgi_state->num_pending_writes_to_peer > CGI_STATE_PENDING_IO_THRESHOLD) + if (cgi->num_pending_writes_to_peer > CGI_PENDING_IO_THRESHOLD) { - if (mio_dev_sck_read(cgi_state->client->sck, 0) <= -1) return -1; + if (mio_dev_sck_read(cgi->client->sck, 0) <= -1) return -1; } return 0; } -static MIO_INLINE void cgi_state_mark_over (cgi_state_t* cgi_state, int over_bits) +static MIO_INLINE void cgi_mark_over (cgi_t* cgi, int over_bits) { unsigned int old_over; - old_over = cgi_state->over; - cgi_state->over |= over_bits; + old_over = cgi->over; + cgi->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); + MIO_DEBUG5 (cgi->htts->mio, "HTTS(%p) - client=%p peer=%p new-bits=%x over=%x\n", cgi->htts, cgi->client->sck, cgi->peer, (int)over_bits, (int)cgi->over); - if (!(old_over & CGI_STATE_OVER_READ_FROM_CLIENT) && (cgi_state->over & CGI_STATE_OVER_READ_FROM_CLIENT)) + if (!(old_over & CGI_OVER_READ_FROM_CLIENT) && (cgi->over & CGI_OVER_READ_FROM_CLIENT)) { - if (mio_dev_sck_read(cgi_state->client->sck, 0) <= -1) + if (mio_dev_sck_read(cgi->client->sck, 0) <= -1) { - MIO_DEBUG2 (cgi_state->htts->mio, "HTTS(%p) - halting client(%p) for failure to disable input watching\n", cgi_state->htts, cgi_state->client->sck); - mio_dev_sck_halt (cgi_state->client->sck); + MIO_DEBUG2 (cgi->htts->mio, "HTTS(%p) - halting client(%p) for failure to disable input watching\n", cgi->htts, cgi->client->sck); + mio_dev_sck_halt (cgi->client->sck); } } - if (!(old_over & CGI_STATE_OVER_READ_FROM_PEER) && (cgi_state->over & CGI_STATE_OVER_READ_FROM_PEER)) + if (!(old_over & CGI_OVER_READ_FROM_PEER) && (cgi->over & CGI_OVER_READ_FROM_PEER)) { - if (cgi_state->peer && mio_dev_pro_read(cgi_state->peer, MIO_DEV_PRO_OUT, 0) <= -1) + if (cgi->peer && mio_dev_pro_read(cgi->peer, MIO_DEV_PRO_OUT, 0) <= -1) { - MIO_DEBUG2 (cgi_state->htts->mio, "HTTS(%p) - halting peer(%p) for failure to disable input watching\n", cgi_state->htts, cgi_state->peer); - mio_dev_pro_halt (cgi_state->peer); + MIO_DEBUG2 (cgi->htts->mio, "HTTS(%p) - halting peer(%p) for failure to disable input watching\n", cgi->htts, cgi->peer); + mio_dev_pro_halt (cgi->peer); } } - if (old_over != CGI_STATE_OVER_ALL && cgi_state->over == CGI_STATE_OVER_ALL) + if (old_over != CGI_OVER_ALL && cgi->over == CGI_OVER_ALL) { /* ready to stop */ - if (cgi_state->peer) + if (cgi->peer) { - MIO_DEBUG2 (cgi_state->htts->mio, "HTTS(%p) - halting peer(%p) as it is unneeded\n", cgi_state->htts, cgi_state->peer); - mio_dev_pro_halt (cgi_state->peer); + MIO_DEBUG2 (cgi->htts->mio, "HTTS(%p) - halting peer(%p) as it is unneeded\n", cgi->htts, cgi->peer); + mio_dev_pro_halt (cgi->peer); } - if (cgi_state->keep_alive) + if (cgi->keep_alive) { - /* 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 == (mio_svc_htts_rsrc_t*)cgi_state); + /* how to arrange to delete this cgi object and put the socket back to the normal waiting state??? */ + MIO_ASSERT (cgi->htts->mio, cgi->client->rsrc == (mio_svc_htts_rsrc_t*)cgi); -printf ("DETACHING FROM THE MAIN CLIENT RSRC... state -> %p\n", cgi_state->client->rsrc); - MIO_SVC_HTTS_RSRC_DETACH (cgi_state->client->rsrc); - /* cgi_state must not be access from here down as it could have been destroyed */ +printf ("DETACHING FROM THE MAIN CLIENT RSRC... state -> %p\n", cgi->client->rsrc); + MIO_SVC_HTTS_RSRC_DETACH (cgi->client->rsrc); + /* cgi must not be access from here down as it could have been destroyed */ } else { - MIO_DEBUG2 (cgi_state->htts->mio, "HTTS(%p) - halting client(%p) for no keep-alive\n", cgi_state->htts, cgi_state->client->sck); - mio_dev_sck_shutdown (cgi_state->client->sck, MIO_DEV_SCK_SHUTDOWN_WRITE); - mio_dev_sck_halt (cgi_state->client->sck); + MIO_DEBUG2 (cgi->htts->mio, "HTTS(%p) - halting client(%p) for no keep-alive\n", cgi->htts, cgi->client->sck); + mio_dev_sck_shutdown (cgi->client->sck, MIO_DEV_SCK_SHUTDOWN_WRITE); + mio_dev_sck_halt (cgi->client->sck); } } } -static void cgi_state_on_kill (cgi_state_t* cgi_state) +static void cgi_on_kill (cgi_t* cgi) { - mio_t* mio = cgi_state->htts->mio; + mio_t* mio = cgi->htts->mio; - MIO_DEBUG2 (mio, "HTTS(%p) - killing cgi_state client(%p)\n", cgi_state->htts, cgi_state->client->sck); + MIO_DEBUG2 (mio, "HTTS(%p) - killing cgi client(%p)\n", cgi->htts, cgi->client->sck); - if (cgi_state->peer) + if (cgi->peer) { - cgi_peer_xtn_t* cgi_peer = mio_dev_pro_getxtn(cgi_state->peer); + cgi_peer_xtn_t* cgi_peer = mio_dev_pro_getxtn(cgi->peer); cgi_peer->state = MIO_NULL; /* cgi_peer->state many not be NULL if the resource is killed regardless of the reference count */ - mio_dev_pro_kill (cgi_state->peer); - cgi_state->peer = MIO_NULL; + mio_dev_pro_kill (cgi->peer); + cgi->peer = MIO_NULL; } - if (cgi_state->peer_htrd) + if (cgi->peer_htrd) { - cgi_peer_xtn_t* cgi_peer = mio_htrd_getxtn(cgi_state->peer_htrd); + cgi_peer_xtn_t* cgi_peer = mio_htrd_getxtn(cgi->peer_htrd); cgi_peer->state = MIO_NULL; /* cgi_peer->state many not be NULL if the resource is killed regardless of the reference count */ - mio_htrd_close (cgi_state->peer_htrd); - cgi_state->peer_htrd = MIO_NULL; + mio_htrd_close (cgi->peer_htrd); + cgi->peer_htrd = MIO_NULL; } - if (cgi_state->client_org_on_read) + if (cgi->client_org_on_read) { - cgi_state->client->sck->on_read = cgi_state->client_org_on_read; - cgi_state->client_org_on_read = MIO_NULL; + cgi->client->sck->on_read = cgi->client_org_on_read; + cgi->client_org_on_read = MIO_NULL; } - if (cgi_state->client_org_on_write) + if (cgi->client_org_on_write) { - cgi_state->client->sck->on_write = cgi_state->client_org_on_write; - cgi_state->client_org_on_write = MIO_NULL; + cgi->client->sck->on_write = cgi->client_org_on_write; + cgi->client_org_on_write = MIO_NULL; } - if (cgi_state->client_org_on_disconnect) + if (cgi->client_org_on_disconnect) { - cgi_state->client->sck->on_disconnect = cgi_state->client_org_on_disconnect; - cgi_state->client_org_on_disconnect = MIO_NULL; + cgi->client->sck->on_disconnect = cgi->client_org_on_disconnect; + cgi->client_org_on_disconnect = MIO_NULL; } - if (cgi_state->client_htrd_recbs_changed) + if (cgi->client_htrd_recbs_changed) { /* restore the callbacks */ - mio_htrd_setrecbs (cgi_state->client->htrd, &cgi_state->client_htrd_org_recbs); + mio_htrd_setrecbs (cgi->client->htrd, &cgi->client_htrd_org_recbs); } - if (!cgi_state->client_disconnected) + if (!cgi->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 ("ENABLING INPUT WATCHING on CLIENT %p. \n", cgi->client->sck);*/ + if (!cgi->keep_alive || mio_dev_sck_read(cgi->client->sck, 1) <= -1) { - MIO_DEBUG2 (mio, "HTTS(%p) - halting client(%p) for failure to enable input watching\n", cgi_state->htts, cgi_state->client->sck); - mio_dev_sck_halt (cgi_state->client->sck); + MIO_DEBUG2 (mio, "HTTS(%p) - halting client(%p) for failure to enable input watching\n", cgi->htts, cgi->client->sck); + mio_dev_sck_halt (cgi->client->sck); } } -/*printf ("**** CGI_STATE_ON_KILL DONE\n");*/ +/*printf ("**** CGI_ON_KILL DONE\n");*/ } static void cgi_peer_on_close (mio_dev_pro_t* pro, mio_dev_pro_sid_t sid) { mio_t* mio = pro->mio; cgi_peer_xtn_t* cgi_peer = mio_dev_pro_getxtn(pro); - cgi_state_t* cgi_state = cgi_peer->state; + cgi_t* cgi = cgi_peer->state; - if (!cgi_state) return; /* cgi state already gone */ + if (!cgi) return; /* cgi state already gone */ switch (sid) { 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); - cgi_state->peer = MIO_NULL; /* clear this peer from the state */ + MIO_DEBUG3 (mio, "HTTS(%p) - peer %p(pid=%d) closing master\n", cgi->client->htts, pro, (int)pro->child_pid); + cgi->peer = MIO_NULL; /* clear this peer from the 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) + if (cgi->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); + cgi_peer = mio_htrd_getxtn(cgi->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); @@ -333,25 +333,25 @@ printf ("DETACHING FROM CGI PEER HTRD.....................%p %d\n", cgi_peer-> break; case MIO_DEV_PRO_OUT: - 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); + MIO_ASSERT (mio, cgi->peer == pro); + MIO_DEBUG4 (mio, "HTTS(%p) - peer %p(pid=%d) closing slave[%d]\n", cgi->client->htts, pro, (int)pro->child_pid, sid); - if (!(cgi_state->over & CGI_STATE_OVER_READ_FROM_PEER)) + if (!(cgi->over & CGI_OVER_READ_FROM_PEER)) { - if (cgi_state_write_last_chunk_to_client(cgi_state) <= -1) - cgi_state_halt_participating_devices (cgi_state); + if (cgi_write_last_chunk_to_client(cgi) <= -1) + cgi_halt_participating_devices (cgi); else - cgi_state_mark_over (cgi_state, CGI_STATE_OVER_READ_FROM_PEER); + cgi_mark_over (cgi, CGI_OVER_READ_FROM_PEER); } break; case MIO_DEV_PRO_IN: - cgi_state_mark_over (cgi_state, CGI_STATE_OVER_WRITE_TO_PEER); + cgi_mark_over (cgi, CGI_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); + MIO_DEBUG4 (mio, "HTTS(%p) - peer %p(pid=%d) closing slave[%d]\n", cgi->client->htts, pro, (int)pro->child_pid, sid); /* do nothing */ break; } @@ -361,44 +361,44 @@ static int cgi_peer_on_read (mio_dev_pro_t* pro, mio_dev_pro_sid_t sid, const vo { mio_t* mio = pro->mio; cgi_peer_xtn_t* cgi_peer = mio_dev_pro_getxtn(pro); - cgi_state_t* cgi_state = cgi_peer->state; + cgi_t* cgi = cgi_peer->state; MIO_ASSERT (mio, sid == MIO_DEV_PRO_OUT); /* since MIO_DEV_PRO_ERRTONUL is used, there should be no input from MIO_DEV_PRO_ERR */ - MIO_ASSERT (mio, cgi_state != MIO_NULL); + MIO_ASSERT (mio, cgi != MIO_NULL); if (dlen <= -1) { - MIO_DEBUG3 (mio, "HTTPS(%p) - read error from peer %p(pid=%u)\n", cgi_state->client->htts, pro, (unsigned int)pro->child_pid); + MIO_DEBUG3 (mio, "HTTPS(%p) - read error from peer %p(pid=%u)\n", cgi->client->htts, pro, (unsigned int)pro->child_pid); goto oops; } if (dlen == 0) { - MIO_DEBUG3 (mio, "HTTPS(%p) - EOF from peer %p(pid=%u)\n", cgi_state->client->htts, pro, (unsigned int)pro->child_pid); + MIO_DEBUG3 (mio, "HTTPS(%p) - EOF from peer %p(pid=%u)\n", cgi->client->htts, pro, (unsigned int)pro->child_pid); - if (!(cgi_state->over & CGI_STATE_OVER_READ_FROM_PEER)) + if (!(cgi->over & CGI_OVER_READ_FROM_PEER)) { /* the cgi script could be misbehaviing. * it still has to read more but EOF is read. * otherwise client_peer_htrd_poke() should have been called */ - if (cgi_state_write_last_chunk_to_client(cgi_state) <= -1) goto oops; - cgi_state_mark_over (cgi_state, CGI_STATE_OVER_READ_FROM_PEER); + if (cgi_write_last_chunk_to_client(cgi) <= -1) goto oops; + cgi_mark_over (cgi, CGI_OVER_READ_FROM_PEER); } } else { mio_oow_t rem; - MIO_ASSERT (mio, !(cgi_state->over & CGI_STATE_OVER_READ_FROM_PEER)); + MIO_ASSERT (mio, !(cgi->over & CGI_OVER_READ_FROM_PEER)); - if (mio_htrd_feed(cgi_state->peer_htrd, data, dlen, &rem) <= -1) + if (mio_htrd_feed(cgi->peer_htrd, data, dlen, &rem) <= -1) { - MIO_DEBUG3 (mio, "HTTPS(%p) - unable to feed peer htrd - peer %p(pid=%u)\n", cgi_state->htts, pro, (unsigned int)pro->child_pid); + MIO_DEBUG3 (mio, "HTTPS(%p) - unable to feed peer htrd - peer %p(pid=%u)\n", cgi->htts, pro, (unsigned int)pro->child_pid); - if (!cgi_state->ever_attempted_to_write_to_client && - !(cgi_state->over & CGI_STATE_OVER_WRITE_TO_CLIENT)) + if (!cgi->ever_attempted_to_write_to_client && + !(cgi->over & CGI_OVER_WRITE_TO_CLIENT)) { - cgi_state_send_final_status_to_client (cgi_state, 500, 1); /* don't care about error because it jumps to oops below anyway */ + cgi_send_final_status_to_client (cgi, 500, 1); /* don't care about error because it jumps to oops below anyway */ } goto oops; @@ -415,7 +415,7 @@ printf ("AAAAAAAAAAAAAAAAAa EEEEEXcessive DATA..................\n"); return 0; oops: - cgi_state_halt_participating_devices (cgi_state); + cgi_halt_participating_devices (cgi); return 0; } @@ -451,15 +451,15 @@ static int cgi_peer_capture_response_header (mio_htre_t* req, const mio_bch_t* k 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_state_t* cgi_state = cgi_peer->state; - mio_svc_htts_cli_t* cli = cgi_state->client; + cgi_t* cgi = cgi_peer->state; + mio_svc_htts_cli_t* cli = cgi->client; mio_bch_t dtbuf[64]; int status_code = 200; if (req->attr.content_length) { // TOOD: remove content_length if content_length is negative or not numeric. - cgi_state->res_mode_to_cli = CGI_STATE_RES_MODE_LENGTH; + cgi->res_mode_to_cli = CGI_RES_MODE_LENGTH; } if (req->attr.status) @@ -476,56 +476,56 @@ printf ("CGI PEER HTRD PEEK...\n"); mio_svc_htts_fmtgmtime (cli->htts, MIO_NULL, dtbuf, MIO_COUNTOF(dtbuf)); if (mio_becs_fmt(cli->sbuf, "HTTP/%d.%d %d %hs\r\nServer: %hs\r\nDate: %hs\r\n", - cgi_state->req_version.major, cgi_state->req_version.minor, + cgi->req_version.major, cgi->req_version.minor, status_code, mio_http_status_to_bcstr(status_code), cli->htts->server_name, dtbuf) == (mio_oow_t)-1) return -1; if (mio_htre_walkheaders(req, cgi_peer_capture_response_header, cli) <= -1) return -1; - switch (cgi_state->res_mode_to_cli) + switch (cgi->res_mode_to_cli) { - case CGI_STATE_RES_MODE_CHUNKED: + case CGI_RES_MODE_CHUNKED: if (mio_becs_cat(cli->sbuf, "Transfer-Encoding: chunked\r\n") == (mio_oow_t)-1) return -1; /*if (mio_becs_cat(cli->sbuf, "Connection: keep-alive\r\n") == (mio_oow_t)-1) return -1;*/ break; - case CGI_STATE_RES_MODE_CLOSE: + case CGI_RES_MODE_CLOSE: if (mio_becs_cat(cli->sbuf, "Connection: close\r\n") == (mio_oow_t)-1) return -1; break; - case CGI_STATE_RES_MODE_LENGTH: - 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; + case CGI_RES_MODE_LENGTH: + if (mio_becs_cat(cli->sbuf, (cgi->keep_alive? "Connection: keep-alive\r\n": "Connection: close\r\n")) == (mio_oow_t)-1) return -1; } if (mio_becs_cat(cli->sbuf, "\r\n") == (mio_oow_t)-1) return -1; - return cgi_state_write_to_client(cgi_state, MIO_BECS_PTR(cli->sbuf), MIO_BECS_LEN(cli->sbuf)); + return cgi_write_to_client(cgi, MIO_BECS_PTR(cli->sbuf), MIO_BECS_LEN(cli->sbuf)); } static int cgi_peer_htrd_poke (mio_htrd_t* htrd, mio_htre_t* req) { /* client request got completed */ cgi_peer_xtn_t* cgi_peer = mio_htrd_getxtn(htrd); - cgi_state_t* cgi_state = cgi_peer->state; + cgi_t* cgi = cgi_peer->state; printf (">> PEER RESPONSE COMPLETED\n"); - if (cgi_state_write_last_chunk_to_client(cgi_state) <= -1) return -1; + if (cgi_write_last_chunk_to_client(cgi) <= -1) return -1; - cgi_state_mark_over (cgi_state, CGI_STATE_OVER_READ_FROM_PEER); + cgi_mark_over (cgi, CGI_OVER_READ_FROM_PEER); return 0; } static int cgi_peer_htrd_push_content (mio_htrd_t* htrd, mio_htre_t* req, const mio_bch_t* data, mio_oow_t dlen) { cgi_peer_xtn_t* cgi_peer = mio_htrd_getxtn(htrd); - cgi_state_t* cgi_state = cgi_peer->state; + cgi_t* cgi = cgi_peer->state; - MIO_ASSERT (cgi_state->client->htts->mio, htrd == cgi_state->peer_htrd); + MIO_ASSERT (cgi->client->htts->mio, htrd == cgi->peer_htrd); - switch (cgi_state->res_mode_to_cli) + switch (cgi->res_mode_to_cli) { - case CGI_STATE_RES_MODE_CHUNKED: + case CGI_RES_MODE_CHUNKED: { mio_iovec_t iov[3]; mio_bch_t lbuf[16]; @@ -544,19 +544,19 @@ static int cgi_peer_htrd_push_content (mio_htrd_t* htrd, mio_htre_t* req, const iov[2].iov_ptr = "\r\n"; iov[2].iov_len = 2; - if (cgi_state_writev_to_client(cgi_state, iov, MIO_COUNTOF(iov)) <= -1) goto oops; + if (cgi_writev_to_client(cgi, iov, MIO_COUNTOF(iov)) <= -1) goto oops; break; } - case CGI_STATE_RES_MODE_CLOSE: - case CGI_STATE_RES_MODE_LENGTH: - if (cgi_state_write_to_client(cgi_state, data, dlen) <= -1) goto oops; + case CGI_RES_MODE_CLOSE: + case CGI_RES_MODE_LENGTH: + if (cgi_write_to_client(cgi, data, dlen) <= -1) goto oops; break; } - if (cgi_state->num_pending_writes_to_client > CGI_STATE_PENDING_IO_THRESHOLD) + if (cgi->num_pending_writes_to_client > CGI_PENDING_IO_THRESHOLD) { - if (mio_dev_pro_read(cgi_state->peer, MIO_DEV_PRO_OUT, 0) <= -1) goto oops; + if (mio_dev_pro_read(cgi->peer, MIO_DEV_PRO_OUT, 0) <= -1) goto oops; } return 0; @@ -578,14 +578,14 @@ static int cgi_client_htrd_poke (mio_htrd_t* htrd, mio_htre_t* req) mio_svc_htts_cli_htrd_xtn_t* htrdxtn = (mio_svc_htts_cli_htrd_xtn_t*)mio_htrd_getxtn(htrd); mio_dev_sck_t* sck = htrdxtn->sck; mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(sck); - cgi_state_t* cgi_state = (cgi_state_t*)cli->rsrc; + cgi_t* cgi = (cgi_t*)cli->rsrc; printf (">> CLIENT REQUEST COMPLETED\n"); /* indicate EOF to the client peer */ - if (cgi_state_write_to_peer(cgi_state, MIO_NULL, 0) <= -1) return -1; + if (cgi_write_to_peer(cgi, MIO_NULL, 0) <= -1) return -1; - cgi_state_mark_over (cgi_state, CGI_STATE_OVER_READ_FROM_CLIENT); + cgi_mark_over (cgi, CGI_OVER_READ_FROM_CLIENT); return 0; } @@ -594,10 +594,10 @@ static int cgi_client_htrd_push_content (mio_htrd_t* htrd, mio_htre_t* req, cons mio_svc_htts_cli_htrd_xtn_t* htrdxtn = (mio_svc_htts_cli_htrd_xtn_t*)mio_htrd_getxtn(htrd); mio_dev_sck_t* sck = htrdxtn->sck; mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(sck); - cgi_state_t* cgi_state = (cgi_state_t*)cli->rsrc; + cgi_t* cgi = (cgi_t*)cli->rsrc; MIO_ASSERT (sck->mio, cli->sck == sck); - return cgi_state_write_to_peer(cgi_state, data, dlen); + return cgi_write_to_peer(cgi, data, dlen); } static mio_htrd_recbs_t cgi_client_htrd_recbs = @@ -611,15 +611,15 @@ static int cgi_peer_on_write (mio_dev_pro_t* pro, mio_iolen_t wrlen, void* wrctx { mio_t* mio = pro->mio; cgi_peer_xtn_t* cgi_peer = mio_dev_pro_getxtn(pro); - cgi_state_t* cgi_state = cgi_peer->state; + cgi_t* cgi = cgi_peer->state; - if (cgi_state == MIO_NULL) return 0; /* there is nothing i can do. the cgi_state is being cleared or has been cleared already. */ + if (cgi == MIO_NULL) return 0; /* there is nothing i can do. the cgi is being cleared or has been cleared already. */ - MIO_ASSERT (mio, cgi_state->peer == pro); + MIO_ASSERT (mio, cgi->peer == pro); if (wrlen <= -1) { - MIO_DEBUG3 (mio, "HTTS(%p) - unable to write to peer %p(pid=%u)\n", cgi_state->client->htts, pro, (int)pro->child_pid); + MIO_DEBUG3 (mio, "HTTS(%p) - unable to write to peer %p(pid=%u)\n", cgi->client->htts, pro, (int)pro->child_pid); goto oops; } else if (wrlen == 0) @@ -627,50 +627,50 @@ static int cgi_peer_on_write (mio_dev_pro_t* pro, mio_iolen_t wrlen, void* wrctx /* indicated EOF */ /* 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--; - 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->client->htts, pro, (int)pro->child_pid); + cgi->num_pending_writes_to_peer--; + MIO_ASSERT (mio, cgi->num_pending_writes_to_peer == 0); + MIO_DEBUG3 (mio, "HTTS(%p) - indicated EOF to peer %p(pid=%u)\n", cgi->client->htts, pro, (int)pro->child_pid); /* 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 */ - cgi_state_mark_over (cgi_state, CGI_STATE_OVER_WRITE_TO_PEER); + cgi_mark_over (cgi, CGI_OVER_WRITE_TO_PEER); } else { - MIO_ASSERT (mio, cgi_state->num_pending_writes_to_peer > 0); + MIO_ASSERT (mio, cgi->num_pending_writes_to_peer > 0); - cgi_state->num_pending_writes_to_peer--; - if (cgi_state->num_pending_writes_to_peer == CGI_STATE_PENDING_IO_THRESHOLD) + cgi->num_pending_writes_to_peer--; + if (cgi->num_pending_writes_to_peer == CGI_PENDING_IO_THRESHOLD) { - if (!(cgi_state->over & CGI_STATE_OVER_READ_FROM_CLIENT) && - mio_dev_sck_read(cgi_state->client->sck, 1) <= -1) goto oops; + if (!(cgi->over & CGI_OVER_READ_FROM_CLIENT) && + mio_dev_sck_read(cgi->client->sck, 1) <= -1) goto oops; } - if ((cgi_state->over & CGI_STATE_OVER_READ_FROM_CLIENT) && cgi_state->num_pending_writes_to_peer <= 0) + if ((cgi->over & CGI_OVER_READ_FROM_CLIENT) && cgi->num_pending_writes_to_peer <= 0) { - cgi_state_mark_over (cgi_state, CGI_STATE_OVER_WRITE_TO_PEER); + cgi_mark_over (cgi, CGI_OVER_WRITE_TO_PEER); } } return 0; oops: - cgi_state_halt_participating_devices (cgi_state); + cgi_halt_participating_devices (cgi); 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; - cgi_state->client_org_on_disconnect (sck); + cgi_t* cgi = (cgi_t*)cli->rsrc; + cgi->client_disconnected = 1; + cgi->client_org_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) { mio_t* mio = sck->mio; mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(sck); - cgi_state_t* cgi_state = (cgi_state_t*)cli->rsrc; + cgi_t* cgi = (cgi_t*)cli->rsrc; MIO_ASSERT (mio, sck == cli->sck); @@ -681,7 +681,7 @@ static int cgi_client_on_read (mio_dev_sck_t* sck, const void* buf, mio_iolen_t goto oops; } - if (!cgi_state->peer) + if (!cgi->peer) { /* the peer is gone */ goto oops; /* do what? just return 0? */ @@ -690,19 +690,19 @@ static int cgi_client_on_read (mio_dev_sck_t* sck, const void* buf, mio_iolen_t if (len == 0) { /* EOF on the client side. arrange to close */ - MIO_DEBUG3 (mio, "HTTPS(%p) - EOF from client %p(hnd=%d)\n", cgi_state->client->htts, sck, (int)sck->hnd); + MIO_DEBUG3 (mio, "HTTPS(%p) - EOF from client %p(hnd=%d)\n", cgi->client->htts, sck, (int)sck->hnd); - if (!(cgi_state->over & CGI_STATE_OVER_READ_FROM_CLIENT)) /* if this is true, EOF is received without cgi_client_htrd_poke() */ + if (!(cgi->over & CGI_OVER_READ_FROM_CLIENT)) /* if this is true, EOF is received without cgi_client_htrd_poke() */ { - if (cgi_state_write_to_peer(cgi_state, MIO_NULL, 0) <= -1) goto oops; - cgi_state_mark_over (cgi_state, CGI_STATE_OVER_READ_FROM_CLIENT); + if (cgi_write_to_peer(cgi, MIO_NULL, 0) <= -1) goto oops; + cgi_mark_over (cgi, CGI_OVER_READ_FROM_CLIENT); } } else { mio_oow_t rem; - MIO_ASSERT (mio, !(cgi_state->over & CGI_STATE_OVER_READ_FROM_CLIENT)); + MIO_ASSERT (mio, !(cgi->over & CGI_OVER_READ_FROM_CLIENT)); if (mio_htrd_feed(cli->htrd, buf, len, &rem) <= -1) goto oops; @@ -716,7 +716,7 @@ static int cgi_client_on_read (mio_dev_sck_t* sck, const void* buf, mio_iolen_t return 0; oops: - cgi_state_halt_participating_devices (cgi_state); + cgi_halt_participating_devices (cgi); return 0; } @@ -724,7 +724,7 @@ static int cgi_client_on_write (mio_dev_sck_t* sck, mio_iolen_t wrlen, void* wrc { mio_t* mio = sck->mio; mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(sck); - cgi_state_t* cgi_state = (cgi_state_t*)cli->rsrc; + cgi_t* cgi = (cgi_t*)cli->rsrc; if (wrlen <= -1) { @@ -735,35 +735,35 @@ static int cgi_client_on_write (mio_dev_sck_t* sck, mio_iolen_t wrlen, void* wrc if (wrlen == 0) { /* if the connect is keep-alive, this part may not be called */ - cgi_state->num_pending_writes_to_client--; - 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->client->htts, sck, (int)sck->hnd); + cgi->num_pending_writes_to_client--; + MIO_ASSERT (mio, cgi->num_pending_writes_to_client == 0); + MIO_DEBUG3 (mio, "HTTS(%p) - indicated EOF to client %p(%d)\n", cgi->client->htts, sck, (int)sck->hnd); /* 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. * i don't need to enable input watching on the peer side */ - cgi_state_mark_over (cgi_state, CGI_STATE_OVER_WRITE_TO_CLIENT); + cgi_mark_over (cgi, CGI_OVER_WRITE_TO_CLIENT); } else { - MIO_ASSERT (mio, cgi_state->num_pending_writes_to_client > 0); + MIO_ASSERT (mio, cgi->num_pending_writes_to_client > 0); - cgi_state->num_pending_writes_to_client--; - if (cgi_state->peer && cgi_state->num_pending_writes_to_client == CGI_STATE_PENDING_IO_THRESHOLD) + cgi->num_pending_writes_to_client--; + if (cgi->peer && cgi->num_pending_writes_to_client == CGI_PENDING_IO_THRESHOLD) { - if (!(cgi_state->over & CGI_STATE_OVER_READ_FROM_PEER) && - mio_dev_pro_read(cgi_state->peer, MIO_DEV_PRO_OUT, 1) <= -1) goto oops; + if (!(cgi->over & CGI_OVER_READ_FROM_PEER) && + mio_dev_pro_read(cgi->peer, MIO_DEV_PRO_OUT, 1) <= -1) goto oops; } - if ((cgi_state->over & CGI_STATE_OVER_READ_FROM_PEER) && cgi_state->num_pending_writes_to_client <= 0) + if ((cgi->over & CGI_OVER_READ_FROM_PEER) && cgi->num_pending_writes_to_client <= 0) { - cgi_state_mark_over (cgi_state, CGI_STATE_OVER_WRITE_TO_CLIENT); + cgi_mark_over (cgi, CGI_OVER_WRITE_TO_CLIENT); } } return 0; oops: - cgi_state_halt_participating_devices (cgi_state); + cgi_halt_participating_devices (cgi); return 0; } @@ -906,7 +906,7 @@ int mio_svc_htts_docgi (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* r { mio_t* mio = htts->mio; mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(csck); - cgi_state_t* cgi_state = MIO_NULL; + cgi_t* cgi = MIO_NULL; cgi_peer_xtn_t* cgi_peer; mio_dev_pro_make_t mi; cgi_peer_fork_ctx_t fc; @@ -931,46 +931,46 @@ int mio_svc_htts_docgi (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* r 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); - if (MIO_UNLIKELY(!cgi_state)) goto oops; + cgi = (cgi_t*)mio_svc_htts_rsrc_make(htts, MIO_SIZEOF(*cgi), cgi_on_kill); + if (MIO_UNLIKELY(!cgi)) goto oops; - cgi_state->client = cli; - /*cgi_state->num_pending_writes_to_client = 0; - cgi_state->num_pending_writes_to_peer = 0;*/ - cgi_state->req_version = *mio_htre_getversion(req); - cgi_state->req_content_length_unlimited = mio_htre_getreqcontentlen(req, &cgi_state->req_content_length); + cgi->client = cli; + /*cgi->num_pending_writes_to_client = 0; + cgi->num_pending_writes_to_peer = 0;*/ + cgi->req_version = *mio_htre_getversion(req); + cgi->req_content_length_unlimited = mio_htre_getreqcontentlen(req, &cgi->req_content_length); - cgi_state->client_org_on_read = csck->on_read; - cgi_state->client_org_on_write = csck->on_write; - cgi_state->client_org_on_disconnect = csck->on_disconnect; + cgi->client_org_on_read = csck->on_read; + cgi->client_org_on_write = csck->on_write; + cgi->client_org_on_disconnect = csck->on_disconnect; csck->on_read = cgi_client_on_read; csck->on_write = cgi_client_on_write; csck->on_disconnect = cgi_client_on_disconnect; MIO_ASSERT (mio, cli->rsrc == MIO_NULL); - MIO_SVC_HTTS_RSRC_ATTACH (cgi_state, cli->rsrc); + MIO_SVC_HTTS_RSRC_ATTACH (cgi, cli->rsrc); if (access(mi.cmd, X_OK) == -1) { - cgi_state_send_final_status_to_client (cgi_state, 403, 1); /* 403 Forbidden */ - goto oops; /* TODO: must not go to oops. just destroy the cgi_state and finalize the request .. */ + cgi_send_final_status_to_client (cgi, 403, 1); /* 403 Forbidden */ + goto oops; /* TODO: must not go to oops. just destroy the cgi and finalize the request .. */ } - cgi_state->peer = mio_dev_pro_make(mio, MIO_SIZEOF(*cgi_peer), &mi); - if (MIO_UNLIKELY(!cgi_state->peer)) goto oops; - cgi_peer = mio_dev_pro_getxtn(cgi_state->peer); - MIO_SVC_HTTS_RSRC_ATTACH (cgi_state, cgi_peer->state); + cgi->peer = mio_dev_pro_make(mio, MIO_SIZEOF(*cgi_peer), &mi); + if (MIO_UNLIKELY(!cgi->peer)) goto oops; + cgi_peer = mio_dev_pro_getxtn(cgi->peer); + MIO_SVC_HTTS_RSRC_ATTACH (cgi, cgi_peer->state); - cgi_state->peer_htrd = mio_htrd_open(mio, MIO_SIZEOF(*cgi_peer)); - if (MIO_UNLIKELY(!cgi_state->peer_htrd)) goto oops; - mio_htrd_setopt (cgi_state->peer_htrd, MIO_HTRD_SKIPINITIALLINE | MIO_HTRD_RESPONSE); - mio_htrd_setrecbs (cgi_state->peer_htrd, &cgi_peer_htrd_recbs); + cgi->peer_htrd = mio_htrd_open(mio, MIO_SIZEOF(*cgi_peer)); + if (MIO_UNLIKELY(!cgi->peer_htrd)) goto oops; + mio_htrd_setopt (cgi->peer_htrd, MIO_HTRD_SKIPINITIALLINE | MIO_HTRD_RESPONSE); + mio_htrd_setrecbs (cgi->peer_htrd, &cgi_peer_htrd_recbs); - cgi_peer = mio_htrd_getxtn(cgi_state->peer_htrd); - MIO_SVC_HTTS_RSRC_ATTACH (cgi_state, cgi_peer->state); + cgi_peer = mio_htrd_getxtn(cgi->peer_htrd); + MIO_SVC_HTTS_RSRC_ATTACH (cgi, cgi_peer->state); #if !defined(CGI_ALLOW_UNLIMITED_REQ_CONTENT_LENGTH) - if (cgi_state->req_content_length_unlimited) + if (cgi->req_content_length_unlimited) { /* Transfer-Encoding is chunked. no content-length is known in advance. */ @@ -978,7 +978,7 @@ int mio_svc_htts_docgi (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* r * option 2. send 411 Length Required immediately * option 3. set Content-Length to -1 and use EOF to indicate the end of content [Non-Standard] */ - if (cgi_state_send_final_status_to_client(cgi_state, 411, 1) <= -1) goto oops; + if (cgi_send_final_status_to_client(cgi, 411, 1) <= -1) goto oops; } #endif @@ -987,7 +987,7 @@ int mio_svc_htts_docgi (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* r /* TODO: Expect: 100-continue? who should handle this? cgi? or the http server? */ /* CAN I LET the cgi SCRIPT handle this? */ if (mio_comp_http_version_numbers(&req->version, 1, 1) >= 0 && - (cgi_state->req_content_length_unlimited || cgi_state->req_content_length > 0)) + (cgi->req_content_length_unlimited || cgi->req_content_length > 0)) { /* * Don't send 100 Continue if http verions is lower than 1.1 @@ -1005,44 +1005,44 @@ int mio_svc_htts_docgi (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* r mio_bch_t msgbuf[64]; mio_oow_t msglen; - msglen = mio_fmttobcstr(mio, msgbuf, MIO_COUNTOF(msgbuf), "HTTP/%d.%d 100 Continue\r\n\r\n", cgi_state->req_version.major, cgi_state->req_version.minor); - if (cgi_state_write_to_client(cgi_state, msgbuf, msglen) <= -1) goto oops; - cgi_state->ever_attempted_to_write_to_client = 0; /* reset this as it's polluted for 100 continue */ + msglen = mio_fmttobcstr(mio, msgbuf, MIO_COUNTOF(msgbuf), "HTTP/%d.%d 100 Continue\r\n\r\n", cgi->req_version.major, cgi->req_version.minor); + if (cgi_write_to_client(cgi, msgbuf, msglen) <= -1) goto oops; + cgi->ever_attempted_to_write_to_client = 0; /* reset this as it's polluted for 100 continue */ } } else if (req->flags & MIO_HTRE_ATTR_EXPECT) { /* 417 Expectation Failed */ - cgi_state_send_final_status_to_client(cgi_state, 417, 1); + cgi_send_final_status_to_client(cgi, 417, 1); goto oops; } #if defined(CGI_ALLOW_UNLIMITED_REQ_CONTENT_LENGTH) - if (cgi_state->req_content_length_unlimited) + if (cgi->req_content_length_unlimited) { /* change the callbacks to subscribe to contents to be uploaded */ - cgi_state->client_htrd_org_recbs = *mio_htrd_getrecbs(cgi_state->client->htrd); - cgi_client_htrd_recbs.peek = cgi_state->client_htrd_org_recbs.peek; - mio_htrd_setrecbs (cgi_state->client->htrd, &cgi_client_htrd_recbs); - cgi_state->client_htrd_recbs_changed = 1; + cgi->client_htrd_org_recbs = *mio_htrd_getrecbs(cgi->client->htrd); + cgi_client_htrd_recbs.peek = cgi->client_htrd_org_recbs.peek; + mio_htrd_setrecbs (cgi->client->htrd, &cgi_client_htrd_recbs); + cgi->client_htrd_recbs_changed = 1; } else { #endif - if (cgi_state->req_content_length > 0) + if (cgi->req_content_length > 0) { /* change the callbacks to subscribe to contents to be uploaded */ - cgi_state->client_htrd_org_recbs = *mio_htrd_getrecbs(cgi_state->client->htrd); - cgi_client_htrd_recbs.peek = cgi_state->client_htrd_org_recbs.peek; - mio_htrd_setrecbs (cgi_state->client->htrd, &cgi_client_htrd_recbs); - cgi_state->client_htrd_recbs_changed = 1; + cgi->client_htrd_org_recbs = *mio_htrd_getrecbs(cgi->client->htrd); + cgi_client_htrd_recbs.peek = cgi->client_htrd_org_recbs.peek; + mio_htrd_setrecbs (cgi->client->htrd, &cgi_client_htrd_recbs); + cgi->client_htrd_recbs_changed = 1; } else { /* no content to be uploaded 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; - cgi_state_mark_over (cgi_state, CGI_STATE_OVER_READ_FROM_CLIENT | CGI_STATE_OVER_WRITE_TO_PEER); + if (cgi_write_to_peer(cgi, MIO_NULL, 0) <= -1) goto oops; + cgi_mark_over (cgi, CGI_OVER_READ_FROM_CLIENT | CGI_OVER_WRITE_TO_PEER); } #if defined(CGI_ALLOW_UNLIMITED_REQ_CONTENT_LENGTH) } @@ -1051,24 +1051,24 @@ int mio_svc_htts_docgi (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* r /* this may change later if Content-Length is included in the cgi output */ 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 */ + cgi->keep_alive = 1; + cgi->res_mode_to_cli = CGI_RES_MODE_CHUNKED; + /* the mode still can get switched to CGI_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; + cgi->keep_alive = 0; + cgi->res_mode_to_cli = CGI_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; + /* TODO: store current input watching state and use it when destroying the cgi data */ + if (mio_dev_sck_read(csck, !(cgi->over & CGI_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 (cgi) cgi_halt_participating_devices (cgi); if (fc.actual_script) mio_freemem (mio, fc.actual_script); return -1; } diff --git a/mio/lib/http-fcgi.c b/mio/lib/http-fcgi.c new file mode 100644 index 0000000..336a865 --- /dev/null +++ b/mio/lib/http-fcgi.c @@ -0,0 +1,86 @@ + +#define FCGI_PADDING_SIZE 255 +#define FCGI_RECORD_SIZE \ + (sizeof(struct fcgi_record_header) + FCGI_CONTENT_SIZE + FCGI_PADDING_SIZE) + +#define FCGI_BEGIN_REQUEST 1 +#define FCGI_ABORT_REQUEST 2 +#define FCGI_END_REQUEST 3 +#define FCGI_PARAMS 4 +#define FCGI_STDIN 5 +#define FCGI_STDOUT 6 +#define FCGI_STDERR 7 +#define FCGI_DATA 8 +#define FCGI_GET_VALUES 9 +#define FCGI_GET_VALUES_RESULT 10 +#define FCGI_UNKNOWN_TYPE 11 +#define FCGI_MAXTYPE (FCGI_UNKNOWN_TYPE) + +/* role in fcgi_begin_request_body */ +#define FCGI_RESPONDER 1 +#define FCGI_AUTHORIZER 2 +#define FCGI_FILTER 3 + +/* flag in fcgi_begin_request_body */ +#define FCGI_KEEP_CONN 1 + +/* proto in fcgi_end_request_body */ +#define FCGI_REQUEST_COMPLETE 0 +#define FCGI_CANT_MPX_CONN 1 +#define FCGI_OVERLOADED 2 +#define FCGI_UNKNOWN_ROLE 3 + +#include "mio-pac1.h" +struct fcgi_record_header +{ + mio_uint8_t version; + mio_uint8_t type; + mio_uint16_t id; + mio_uint16_t content_len; + mio_uint8_t padding_len; + mio_uint8_t reserved; +}; + +struct fcgi_begin_request_body +{ + mio_uint16_t role; + mio_uint8_t flags; + mio_uint8_t reserved[5]; +}; + +struct fcgi_end_request_body +{ + mio_uint32_t app_status; + mio_uint8_t proto_status; + mio_uint8_t reserved[3]; +}; +#include "mio-upac.h" + + + + + +static int begin_request () +{ + struct fcgi_record_header* h; + struct fcgi_begin_request_body* br; + + h->version = 1; + h->type = FCGI_BEGIN_REQUEST; + h->id = MIO_CONST_HTON16(1); + h->content_len = MIO_HTON16(MIO_SIZEOF(struct fcgi_begin_request_body)); + h->padding_len = 0; + + br->role = MIO_CONST_HTON16(FCGI_RESPONDER); + br->flags = 0; + + + h->type = FCGI_PARAMS; + h->content_len = 0; + + +/* + h->type = FCGI_STDIN; +*/ + +} diff --git a/mio/lib/http-fil.c b/mio/lib/http-fil.c index 86c5166..aeb7cc2 100644 --- a/mio/lib/http-fil.c +++ b/mio/lib/http-fil.c @@ -38,22 +38,22 @@ #define FILE_ALLOW_UNLIMITED_REQ_CONTENT_LENGTH -enum file_state_res_mode_t +enum file_res_mode_t { - FILE_STATE_RES_MODE_CLOSE, - FILE_STATE_RES_MODE_LENGTH + FILE_RES_MODE_CLOSE, + FILE_RES_MODE_LENGTH }; -typedef enum file_state_res_mode_t file_state_res_mode_t; +typedef enum file_res_mode_t file_res_mode_t; -#define FILE_STATE_PENDING_IO_THRESHOLD 5 +#define FILE_PENDING_IO_THRESHOLD 5 -#define FILE_STATE_OVER_READ_FROM_CLIENT (1 << 0) -#define FILE_STATE_OVER_READ_FROM_PEER (1 << 1) -#define FILE_STATE_OVER_WRITE_TO_CLIENT (1 << 2) -#define FILE_STATE_OVER_WRITE_TO_PEER (1 << 3) -#define FILE_STATE_OVER_ALL (FILE_STATE_OVER_READ_FROM_CLIENT | FILE_STATE_OVER_READ_FROM_PEER | FILE_STATE_OVER_WRITE_TO_CLIENT | FILE_STATE_OVER_WRITE_TO_PEER) +#define FILE_OVER_READ_FROM_CLIENT (1 << 0) +#define FILE_OVER_READ_FROM_PEER (1 << 1) +#define FILE_OVER_WRITE_TO_CLIENT (1 << 2) +#define FILE_OVER_WRITE_TO_PEER (1 << 3) +#define FILE_OVER_ALL (FILE_OVER_READ_FROM_CLIENT | FILE_OVER_READ_FROM_PEER | FILE_OVER_WRITE_TO_CLIENT | FILE_OVER_WRITE_TO_PEER) -struct file_state_t +struct file_t { MIO_SVC_HTTS_RSRC_HEADER; @@ -74,7 +74,7 @@ struct file_state_t mio_http_version_t req_version; /* client request */ mio_http_method_t req_method; - unsigned int over: 4; /* must be large enough to accomodate FILE_STATE_OVER_ALL */ + unsigned int over: 4; /* must be large enough to accomodate FILE_OVER_ALL */ unsigned int keep_alive: 1; unsigned int req_content_length_unlimited: 1; unsigned int ever_attempted_to_write_to_client: 1; @@ -82,7 +82,7 @@ struct file_state_t unsigned int client_htrd_recbs_changed: 1; unsigned int etag_match: 1; mio_oow_t req_content_length; /* client request content length */ - file_state_res_mode_t res_mode_to_cli; + file_res_mode_t res_mode_to_cli; mio_dev_sck_on_read_t client_org_on_read; mio_dev_sck_on_write_t client_org_on_write; @@ -90,209 +90,209 @@ struct file_state_t mio_htrd_recbs_t client_htrd_org_recbs; }; -typedef struct file_state_t file_state_t; +typedef struct file_t file_t; -static int file_state_send_contents_to_client (file_state_t* file_state); +static int file_send_contents_to_client (file_t* file); -static void file_state_halt_participating_devices (file_state_t* file_state) +static void file_halt_participating_devices (file_t* file) { - MIO_ASSERT (file_state->client->htts->mio, file_state->client != MIO_NULL); - MIO_ASSERT (file_state->client->htts->mio, file_state->client->sck != MIO_NULL); + MIO_ASSERT (file->client->htts->mio, file->client != MIO_NULL); + MIO_ASSERT (file->client->htts->mio, file->client->sck != MIO_NULL); - MIO_DEBUG4 (file_state->client->htts->mio, "HTTS(%p) - Halting participating devices in file state %p(client=%p,peer=%d)\n", file_state->client->htts, file_state, file_state->client->sck, (int)file_state->peer); + MIO_DEBUG4 (file->client->htts->mio, "HTTS(%p) - Halting participating devices in file state %p(client=%p,peer=%d)\n", file->client->htts, file, file->client->sck, (int)file->peer); - mio_dev_sck_halt (file_state->client->sck); + mio_dev_sck_halt (file->client->sck); } -static int file_state_write_to_client (file_state_t* file_state, const void* data, mio_iolen_t dlen) +static int file_write_to_client (file_t* file, const void* data, mio_iolen_t dlen) { - file_state->ever_attempted_to_write_to_client = 1; + file->ever_attempted_to_write_to_client = 1; - file_state->num_pending_writes_to_client++; - if (mio_dev_sck_write(file_state->client->sck, data, dlen, MIO_NULL, MIO_NULL) <= -1) /* TODO: use sendfile here.. */ + file->num_pending_writes_to_client++; + if (mio_dev_sck_write(file->client->sck, data, dlen, MIO_NULL, MIO_NULL) <= -1) /* TODO: use sendfile here.. */ { - file_state->num_pending_writes_to_client--; + file->num_pending_writes_to_client--; return -1; } - if (file_state->num_pending_writes_to_client > FILE_STATE_PENDING_IO_THRESHOLD) + if (file->num_pending_writes_to_client > FILE_PENDING_IO_THRESHOLD) { /* STOP READING */ - /*if (mio_dev_pro_read(file_state->peer, MIO_DEV_PRO_OUT, 0) <= -1) return -1;*/ + /*if (mio_dev_pro_read(file->peer, MIO_DEV_PRO_OUT, 0) <= -1) return -1;*/ } return 0; } -static int file_state_sendfile_to_client (file_state_t* file_state, mio_foff_t foff, mio_iolen_t len) +static int file_sendfile_to_client (file_t* file, mio_foff_t foff, mio_iolen_t len) { - file_state->ever_attempted_to_write_to_client = 1; + file->ever_attempted_to_write_to_client = 1; - file_state->num_pending_writes_to_client++; - if (mio_dev_sck_sendfile(file_state->client->sck, file_state->peer, foff, len, MIO_NULL) <= -1) + file->num_pending_writes_to_client++; + if (mio_dev_sck_sendfile(file->client->sck, file->peer, foff, len, MIO_NULL) <= -1) { - file_state->num_pending_writes_to_client--; + file->num_pending_writes_to_client--; return -1; } - if (file_state->num_pending_writes_to_client > FILE_STATE_PENDING_IO_THRESHOLD) + if (file->num_pending_writes_to_client > FILE_PENDING_IO_THRESHOLD) { /* STOP READING */ - /*if (mio_dev_pro_read(file_state->peer, MIO_DEV_PRO_OUT, 0) <= -1) return -1;*/ + /*if (mio_dev_pro_read(file->peer, MIO_DEV_PRO_OUT, 0) <= -1) return -1;*/ } return 0; } -static int file_state_send_final_status_to_client (file_state_t* file_state, int status_code, int force_close) +static int file_send_final_status_to_client (file_t* file, int status_code, int force_close) { - mio_svc_htts_cli_t* cli = file_state->client; + mio_svc_htts_cli_t* cli = file->client; mio_bch_t dtbuf[64]; mio_svc_htts_fmtgmtime (cli->htts, MIO_NULL, dtbuf, MIO_COUNTOF(dtbuf)); - if (!force_close) force_close = !file_state->keep_alive; + if (!force_close) force_close = !file->keep_alive; if (mio_becs_fmt(cli->sbuf, "HTTP/%d.%d %d %hs\r\nServer: %hs\r\nDate: %s\r\nConnection: %hs\r\nContent-Length: 0\r\n\r\n", - file_state->req_version.major, file_state->req_version.minor, + file->req_version.major, file->req_version.minor, status_code, mio_http_status_to_bcstr(status_code), cli->htts->server_name, dtbuf, (force_close? "close": "keep-alive")) == (mio_oow_t)-1) return -1; - return (file_state_write_to_client(file_state, MIO_BECS_PTR(cli->sbuf), MIO_BECS_LEN(cli->sbuf)) <= -1 || - (force_close && file_state_write_to_client(file_state, MIO_NULL, 0) <= -1))? -1: 0; + return (file_write_to_client(file, MIO_BECS_PTR(cli->sbuf), MIO_BECS_LEN(cli->sbuf)) <= -1 || + (force_close && file_write_to_client(file, MIO_NULL, 0) <= -1))? -1: 0; } -static void file_state_close_peer (file_state_t* file_state) +static void file_close_peer (file_t* file) { - mio_t* mio = file_state->htts->mio; + mio_t* mio = file->htts->mio; - if (file_state->peer_tmridx != MIO_TMRIDX_INVALID) + if (file->peer_tmridx != MIO_TMRIDX_INVALID) { - mio_deltmrjob (mio, file_state->peer_tmridx); - MIO_ASSERT (mio, file_state->peer_tmridx == MIO_TMRIDX_INVALID); + mio_deltmrjob (mio, file->peer_tmridx); + MIO_ASSERT (mio, file->peer_tmridx == MIO_TMRIDX_INVALID); } - if (file_state->peer >= 0) + if (file->peer >= 0) { - close (file_state->peer); - file_state->peer = -1; + close (file->peer); + file->peer = -1; } } -static void file_state_mark_over (file_state_t* file_state, int over_bits) +static void file_mark_over (file_t* file, int over_bits) { unsigned int old_over; - old_over = file_state->over; - file_state->over |= over_bits; + old_over = file->over; + file->over |= over_bits; - MIO_DEBUG5 (file_state->htts->mio, "HTTS(%p) - client=%p peer=%p new-bits=%x over=%x\n", file_state->htts, file_state->client->sck, file_state->peer, (int)over_bits, (int)file_state->over); + MIO_DEBUG5 (file->htts->mio, "HTTS(%p) - client=%p peer=%p new-bits=%x over=%x\n", file->htts, file->client->sck, file->peer, (int)over_bits, (int)file->over); - if (!(old_over & FILE_STATE_OVER_READ_FROM_CLIENT) && (file_state->over & FILE_STATE_OVER_READ_FROM_CLIENT)) + if (!(old_over & FILE_OVER_READ_FROM_CLIENT) && (file->over & FILE_OVER_READ_FROM_CLIENT)) { - if (mio_dev_sck_read(file_state->client->sck, 0) <= -1) + if (mio_dev_sck_read(file->client->sck, 0) <= -1) { - MIO_DEBUG2 (file_state->htts->mio, "HTTS(%p) - halting client(%p) for failure to disable input watching\n", file_state->htts, file_state->client->sck); - mio_dev_sck_halt (file_state->client->sck); + MIO_DEBUG2 (file->htts->mio, "HTTS(%p) - halting client(%p) for failure to disable input watching\n", file->htts, file->client->sck); + mio_dev_sck_halt (file->client->sck); } } #if 0 - if (!(old_over & FILE_STATE_OVER_READ_FROM_PEER) && (file_state->over & FILE_STATE_OVER_READ_FROM_PEER)) + if (!(old_over & FILE_OVER_READ_FROM_PEER) && (file->over & FILE_OVER_READ_FROM_PEER)) { /* there is no partial close... keep it open */ } #endif - if (old_over != FILE_STATE_OVER_ALL && file_state->over == FILE_STATE_OVER_ALL) + if (old_over != FILE_OVER_ALL && file->over == FILE_OVER_ALL) { /* ready to stop */ - MIO_DEBUG2 (file_state->htts->mio, "HTTS(%p) - halting peer(%p) as it is unneeded\n", file_state->htts, file_state->peer); - file_state_close_peer (file_state); + MIO_DEBUG2 (file->htts->mio, "HTTS(%p) - halting peer(%p) as it is unneeded\n", file->htts, file->peer); + file_close_peer (file); - if (file_state->keep_alive) + if (file->keep_alive) { #if defined(TCP_CORK) int tcp_cork = 0; #if defined(SOL_TCP) - mio_dev_sck_setsockopt(file_state->client->sck, SOL_TCP, TCP_CORK, &tcp_cork, MIO_SIZEOF(tcp_cork)); + mio_dev_sck_setsockopt(file->client->sck, SOL_TCP, TCP_CORK, &tcp_cork, MIO_SIZEOF(tcp_cork)); #elif defined(IPPROTO_TCP) - mio_dev_sck_setsockopt(file_state->client->sck, IPPROTO_TCP, TCP_CORK, &tcp_cork, MIO_SIZEOF(tcp_cork)); + mio_dev_sck_setsockopt(file->client->sck, IPPROTO_TCP, TCP_CORK, &tcp_cork, MIO_SIZEOF(tcp_cork)); #endif #endif - /* how to arrange to delete this file_state object and put the socket back to the normal waiting state??? */ - MIO_ASSERT (file_state->htts->mio, file_state->client->rsrc == (mio_svc_htts_rsrc_t*)file_state); + /* how to arrange to delete this file object and put the socket back to the normal waiting state??? */ + MIO_ASSERT (file->htts->mio, file->client->rsrc == (mio_svc_htts_rsrc_t*)file); - MIO_SVC_HTTS_RSRC_DETACH (file_state->client->rsrc); - /* file_state must not be accessed from here down as it could have been destroyed */ + MIO_SVC_HTTS_RSRC_DETACH (file->client->rsrc); + /* file must not be accessed from here down as it could have been destroyed */ } else { - MIO_DEBUG2 (file_state->htts->mio, "HTTS(%p) - halting client(%p) for no keep-alive\n", file_state->htts, file_state->client->sck); - mio_dev_sck_shutdown (file_state->client->sck, MIO_DEV_SCK_SHUTDOWN_WRITE); - mio_dev_sck_halt (file_state->client->sck); + MIO_DEBUG2 (file->htts->mio, "HTTS(%p) - halting client(%p) for no keep-alive\n", file->htts, file->client->sck); + mio_dev_sck_shutdown (file->client->sck, MIO_DEV_SCK_SHUTDOWN_WRITE); + mio_dev_sck_halt (file->client->sck); } } } -static int file_state_write_to_peer (file_state_t* file_state, const void* data, mio_iolen_t dlen) +static int file_write_to_peer (file_t* file, const void* data, mio_iolen_t dlen) { - mio_t* mio = file_state->htts->mio; + mio_t* mio = file->htts->mio; if (dlen <= 0) { - file_state_mark_over (file_state, FILE_STATE_OVER_WRITE_TO_PEER); + file_mark_over (file, FILE_OVER_WRITE_TO_PEER); } else { - if (file_state->req_method == MIO_HTTP_GET) return 0; + if (file->req_method == MIO_HTTP_GET) return 0; - MIO_ASSERT (mio, file_state->peer >= 0); - return write(file_state->peer, data, dlen) <= -1? -1: 0; + MIO_ASSERT (mio, file->peer >= 0); + return write(file->peer, data, dlen) <= -1? -1: 0; } return 0; } -static void file_state_on_kill (file_state_t* file_state) +static void file_on_kill (file_t* file) { - mio_t* mio = file_state->htts->mio; + mio_t* mio = file->htts->mio; - MIO_DEBUG2 (mio, "HTTS(%p) - killing file client(%p)\n", file_state->htts, file_state->client->sck); + MIO_DEBUG2 (mio, "HTTS(%p) - killing file client(%p)\n", file->htts, file->client->sck); - file_state_close_peer (file_state); + file_close_peer (file); - if (file_state->client_org_on_read) + if (file->client_org_on_read) { - file_state->client->sck->on_read = file_state->client_org_on_read; - file_state->client_org_on_read = MIO_NULL; + file->client->sck->on_read = file->client_org_on_read; + file->client_org_on_read = MIO_NULL; } - if (file_state->client_org_on_write) + if (file->client_org_on_write) { - file_state->client->sck->on_write = file_state->client_org_on_write; - file_state->client_org_on_write = MIO_NULL; + file->client->sck->on_write = file->client_org_on_write; + file->client_org_on_write = MIO_NULL; } - if (file_state->client_org_on_disconnect) + if (file->client_org_on_disconnect) { - file_state->client->sck->on_disconnect = file_state->client_org_on_disconnect; - file_state->client_org_on_disconnect = MIO_NULL; + file->client->sck->on_disconnect = file->client_org_on_disconnect; + file->client_org_on_disconnect = MIO_NULL; } - if (file_state->client_htrd_recbs_changed) + if (file->client_htrd_recbs_changed) { /* restore the callbacks */ - mio_htrd_setrecbs (file_state->client->htrd, &file_state->client_htrd_org_recbs); + mio_htrd_setrecbs (file->client->htrd, &file->client_htrd_org_recbs); } - if (!file_state->client_disconnected) + if (!file->client_disconnected) { - if (!file_state->keep_alive || mio_dev_sck_read(file_state->client->sck, 1) <= -1) + if (!file->keep_alive || mio_dev_sck_read(file->client->sck, 1) <= -1) { - MIO_DEBUG2 (mio, "HTTS(%p) - halting client(%p) for failure to enable input watching\n", file_state->htts, file_state->client->sck); - mio_dev_sck_halt (file_state->client->sck); + MIO_DEBUG2 (mio, "HTTS(%p) - halting client(%p) for failure to enable input watching\n", file->htts, file->client->sck); + mio_dev_sck_halt (file->client->sck); } } } @@ -300,16 +300,16 @@ static void file_state_on_kill (file_state_t* file_state) static void file_client_on_disconnect (mio_dev_sck_t* sck) { mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(sck); - file_state_t* file_state = (file_state_t*)cli->rsrc; - file_state->client_disconnected = 1; - file_state->client_org_on_disconnect (sck); + file_t* file = (file_t*)cli->rsrc; + file->client_disconnected = 1; + file->client_org_on_disconnect (sck); } static int file_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_svc_htts_cli_t* cli = mio_dev_sck_getxtn(sck); - file_state_t* file_state = (file_state_t*)cli->rsrc; + file_t* file = (file_t*)cli->rsrc; MIO_ASSERT (mio, sck == cli->sck); @@ -320,7 +320,7 @@ static int file_client_on_read (mio_dev_sck_t* sck, const void* buf, mio_iolen_t goto oops; } - if (!file_state->peer) + if (!file->peer) { /* the peer is gone */ goto oops; /* do what? just return 0? */ @@ -329,19 +329,19 @@ static int file_client_on_read (mio_dev_sck_t* sck, const void* buf, mio_iolen_t if (len == 0) { /* EOF on the client side. arrange to close */ - MIO_DEBUG3 (mio, "HTTPS(%p) - EOF from client %p(hnd=%d)\n", file_state->client->htts, sck, (int)sck->hnd); + MIO_DEBUG3 (mio, "HTTPS(%p) - EOF from client %p(hnd=%d)\n", file->client->htts, sck, (int)sck->hnd); - if (!(file_state->over & FILE_STATE_OVER_READ_FROM_CLIENT)) /* if this is true, EOF is received without file_client_htrd_poke() */ + if (!(file->over & FILE_OVER_READ_FROM_CLIENT)) /* if this is true, EOF is received without file_client_htrd_poke() */ { - if (file_state_write_to_peer(file_state, MIO_NULL, 0) <= -1) goto oops; - file_state_mark_over (file_state, FILE_STATE_OVER_READ_FROM_CLIENT); + if (file_write_to_peer(file, MIO_NULL, 0) <= -1) goto oops; + file_mark_over (file, FILE_OVER_READ_FROM_CLIENT); } } else { mio_oow_t rem; - MIO_ASSERT (mio, !(file_state->over & FILE_STATE_OVER_READ_FROM_CLIENT)); + MIO_ASSERT (mio, !(file->over & FILE_OVER_READ_FROM_CLIENT)); if (mio_htrd_feed(cli->htrd, buf, len, &rem) <= -1) goto oops; @@ -355,7 +355,7 @@ static int file_client_on_read (mio_dev_sck_t* sck, const void* buf, mio_iolen_t return 0; oops: - file_state_halt_participating_devices (file_state); + file_halt_participating_devices (file); return 0; } @@ -363,7 +363,7 @@ static int file_client_on_write (mio_dev_sck_t* sck, mio_iolen_t wrlen, void* wr { mio_t* mio = sck->mio; mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(sck); - file_state_t* file_state = (file_state_t*)cli->rsrc; + file_t* file = (file_t*)cli->rsrc; if (wrlen <= -1) { @@ -374,33 +374,33 @@ static int file_client_on_write (mio_dev_sck_t* sck, mio_iolen_t wrlen, void* wr if (wrlen == 0) { /* if the connect is keep-alive, this part may not be called */ - file_state->num_pending_writes_to_client--; - MIO_ASSERT (mio, file_state->num_pending_writes_to_client == 0); - MIO_DEBUG3 (mio, "HTTS(%p) - indicated EOF to client %p(%d)\n", file_state->client->htts, sck, (int)sck->hnd); + file->num_pending_writes_to_client--; + MIO_ASSERT (mio, file->num_pending_writes_to_client == 0); + MIO_DEBUG3 (mio, "HTTS(%p) - indicated EOF to client %p(%d)\n", file->client->htts, sck, (int)sck->hnd); /* 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. * i don't need to enable input watching on the peer side */ - file_state_mark_over (file_state, FILE_STATE_OVER_WRITE_TO_CLIENT); + file_mark_over (file, FILE_OVER_WRITE_TO_CLIENT); } else { - MIO_ASSERT (mio, file_state->num_pending_writes_to_client > 0); - file_state->num_pending_writes_to_client--; + MIO_ASSERT (mio, file->num_pending_writes_to_client > 0); + file->num_pending_writes_to_client--; - if (file_state->req_method == MIO_HTTP_GET) - file_state_send_contents_to_client (file_state); + if (file->req_method == MIO_HTTP_GET) + file_send_contents_to_client (file); - if ((file_state->over & FILE_STATE_OVER_READ_FROM_PEER) && file_state->num_pending_writes_to_client <= 0) + if ((file->over & FILE_OVER_READ_FROM_PEER) && file->num_pending_writes_to_client <= 0) { - file_state_mark_over (file_state, FILE_STATE_OVER_WRITE_TO_CLIENT); + file_mark_over (file, FILE_OVER_WRITE_TO_CLIENT); } } return 0; oops: - file_state_halt_participating_devices (file_state); + file_halt_participating_devices (file); return 0; } @@ -413,17 +413,17 @@ static int file_client_htrd_poke (mio_htrd_t* htrd, mio_htre_t* req) mio_svc_htts_cli_htrd_xtn_t* htrdxtn = (mio_svc_htts_cli_htrd_xtn_t*)mio_htrd_getxtn(htrd); mio_dev_sck_t* sck = htrdxtn->sck; mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(sck); - file_state_t* file_state = (file_state_t*)cli->rsrc; + file_t* file = (file_t*)cli->rsrc; /* indicate EOF to the client peer */ - if (file_state_write_to_peer(file_state, MIO_NULL, 0) <= -1) return -1; + if (file_write_to_peer(file, MIO_NULL, 0) <= -1) return -1; - if (file_state->req_method != MIO_HTTP_GET) + if (file->req_method != MIO_HTTP_GET) { - if (file_state_send_final_status_to_client(file_state, 200, 0) <= -1) return -1; + if (file_send_final_status_to_client(file, 200, 0) <= -1) return -1; } - file_state_mark_over (file_state, FILE_STATE_OVER_READ_FROM_CLIENT); + file_mark_over (file, FILE_OVER_READ_FROM_CLIENT); return 0; } @@ -432,10 +432,10 @@ static int file_client_htrd_push_content (mio_htrd_t* htrd, mio_htre_t* req, con mio_svc_htts_cli_htrd_xtn_t* htrdxtn = (mio_svc_htts_cli_htrd_xtn_t*)mio_htrd_getxtn(htrd); mio_dev_sck_t* sck = htrdxtn->sck; mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(sck); - file_state_t* file_state = (file_state_t*)cli->rsrc; + file_t* file = (file_t*)cli->rsrc; MIO_ASSERT (sck->mio, cli->sck == sck); - return file_state_write_to_peer(file_state, data, dlen); + return file_write_to_peer(file, data, dlen); } static mio_htrd_recbs_t file_client_htrd_recbs = @@ -447,27 +447,27 @@ static mio_htrd_recbs_t file_client_htrd_recbs = /* --------------------------------------------------------------------- */ -static int file_state_send_header_to_client (file_state_t* file_state, int status_code, int force_close, const mio_bch_t* mime_type) +static int file_send_header_to_client (file_t* file, int status_code, int force_close, const mio_bch_t* mime_type) { - mio_svc_htts_cli_t* cli = file_state->client; + mio_svc_htts_cli_t* cli = file->client; mio_bch_t dtbuf[64]; mio_foff_t content_length; mio_svc_htts_fmtgmtime (cli->htts, MIO_NULL, dtbuf, MIO_COUNTOF(dtbuf)); - if (!force_close) force_close = !file_state->keep_alive; + if (!force_close) force_close = !file->keep_alive; - content_length = file_state->end_offset - file_state->start_offset + 1; - if (status_code == 200 && file_state->total_size != content_length) status_code = 206; + content_length = file->end_offset - file->start_offset + 1; + if (status_code == 200 && file->total_size != content_length) status_code = 206; if (mio_becs_fmt(cli->sbuf, "HTTP/%d.%d %d %hs\r\nServer: %hs\r\nDate: %s\r\nConnection: %hs\r\nAccept-Ranges: bytes\r\nContent-Type: %hs\r\n", - file_state->req_version.major, file_state->req_version.minor, + file->req_version.major, file->req_version.minor, status_code, mio_http_status_to_bcstr(status_code), cli->htts->server_name, dtbuf, (force_close? "close": "keep-alive"), mime_type) == (mio_oow_t)-1) return -1; - if (file_state->req_method == MIO_HTTP_GET && mio_becs_fcat(cli->sbuf, "ETag: %hs\r\n", file_state->peer_etag) == (mio_oow_t)-1) return -1; - if (status_code == 206 && mio_becs_fcat(cli->sbuf, "Content-Ranges: bytes %ju-%ju/%ju\r\n", (mio_uintmax_t)file_state->start_offset, (mio_uintmax_t)file_state->end_offset, (mio_uintmax_t)file_state->total_size) == (mio_oow_t)-1) return -1; + if (file->req_method == MIO_HTTP_GET && mio_becs_fcat(cli->sbuf, "ETag: %hs\r\n", file->peer_etag) == (mio_oow_t)-1) return -1; + if (status_code == 206 && mio_becs_fcat(cli->sbuf, "Content-Ranges: bytes %ju-%ju/%ju\r\n", (mio_uintmax_t)file->start_offset, (mio_uintmax_t)file->end_offset, (mio_uintmax_t)file->total_size) == (mio_oow_t)-1) return -1; /* ----- */ // TODO: Allow-Contents @@ -477,53 +477,53 @@ static int file_state_send_header_to_client (file_state_t* file_state, int statu if (mio_becs_fcat(cli->sbuf, "Content-Length: %ju\r\n\r\n", (mio_uintmax_t)content_length) == (mio_oow_t)-1) return -1; - return file_state_write_to_client(file_state, MIO_BECS_PTR(cli->sbuf), MIO_BECS_LEN(cli->sbuf)); + return file_write_to_client(file, MIO_BECS_PTR(cli->sbuf), MIO_BECS_LEN(cli->sbuf)); } static void send_contents_to_client_later (mio_t* mio, const mio_ntime_t* now, mio_tmrjob_t* tmrjob) { - file_state_t* file_state = (file_state_t*)tmrjob->ctx; - if (file_state_send_contents_to_client(file_state) <= -1) + file_t* file = (file_t*)tmrjob->ctx; + if (file_send_contents_to_client(file) <= -1) { - file_state_halt_participating_devices (file_state); + file_halt_participating_devices (file); } } -static int file_state_send_contents_to_client (file_state_t* file_state) +static int file_send_contents_to_client (file_t* file) { - mio_t* mio = file_state->htts->mio; + mio_t* mio = file->htts->mio; mio_foff_t lim; - if (file_state->cur_offset > file_state->end_offset) + if (file->cur_offset > file->end_offset) { /* reached the end */ - file_state_mark_over (file_state, FILE_STATE_OVER_READ_FROM_PEER); + file_mark_over (file, FILE_OVER_READ_FROM_PEER); return 0; } - lim = file_state->end_offset - file_state->cur_offset + 1; - if (file_state->sendfile_ok) + lim = file->end_offset - file->cur_offset + 1; + if (file->sendfile_ok) { if (lim > 0x7FFF0000) lim = 0x7FFF0000; /* TODO: change this... */ - if (file_state_sendfile_to_client(file_state, file_state->cur_offset, lim) <= -1) return -1; - file_state->cur_offset += lim; + if (file_sendfile_to_client(file, file->cur_offset, lim) <= -1) return -1; + file->cur_offset += lim; } else { ssize_t n; - n = read(file_state->peer, file_state->peer_buf, (lim < MIO_SIZEOF(file_state->peer_buf)? lim: MIO_SIZEOF(file_state->peer_buf))); + n = read(file->peer, file->peer_buf, (lim < MIO_SIZEOF(file->peer_buf)? lim: MIO_SIZEOF(file->peer_buf))); if (n == -1) { - if ((errno == EAGAIN || errno == EINTR) && file_state->peer_tmridx == MIO_TMRIDX_INVALID) + if ((errno == EAGAIN || errno == EINTR) && file->peer_tmridx == MIO_TMRIDX_INVALID) { mio_tmrjob_t tmrjob; /* use a timer job for a new sending attempt */ MIO_MEMSET (&tmrjob, 0, MIO_SIZEOF(tmrjob)); - tmrjob.ctx = file_state; + tmrjob.ctx = file; /*tmrjob.when = leave it at 0 for immediate firing.*/ tmrjob.handler = send_contents_to_client_later; - tmrjob.idxptr = &file_state->peer_tmridx; + tmrjob.idxptr = &file->peer_tmridx; return mio_instmrjob(mio, &tmrjob) == MIO_TMRIDX_INVALID? -1: 0; } @@ -533,56 +533,56 @@ static int file_state_send_contents_to_client (file_state_t* file_state) { /* no more data to read - this must not happend unless file size changed while the file is open. */ /* TODO: I probably must close the connection by force??? */ - file_state_mark_over (file_state, FILE_STATE_OVER_READ_FROM_PEER); + file_mark_over (file, FILE_OVER_READ_FROM_PEER); return -1; } - if (file_state_write_to_client(file_state, file_state->peer_buf, n) <= -1) return -1; + if (file_write_to_client(file, file->peer_buf, n) <= -1) return -1; - file_state->cur_offset += n; + file->cur_offset += n; - /* if (file_state->cur_offset > file_state->end_offset) should i check this or wait until this function is invoked? - file_state_mark_over (file_state, FILE_STATE_OVER_READ_FROM_PEER);*/ + /* if (file->cur_offset > file->end_offset) should i check this or wait until this function is invoked? + file_mark_over (file, FILE_OVER_READ_FROM_PEER);*/ } return 0; } -static MIO_INLINE int process_range_header (file_state_t* file_state, mio_htre_t* req) +static MIO_INLINE int process_range_header (file_t* file, mio_htre_t* req) { struct stat st; const mio_htre_hdrval_t* tmp; mio_oow_t etag_len; - if (fstat(file_state->peer, &st) <= -1) + if (fstat(file->peer, &st) <= -1) { - file_state_send_final_status_to_client (file_state, 500, 1); + file_send_final_status_to_client (file, 500, 1); return -1; } if ((st.st_mode & S_IFMT) != S_IFREG) { /* TODO: support directory listing if S_IFDIR? still disallow special files. */ - file_state_send_final_status_to_client (file_state, 403, 1); /* forbidden */ + file_send_final_status_to_client (file, 403, 1); /* forbidden */ return -1; } - if (file_state->req_method == MIO_HTTP_GET) + if (file->req_method == MIO_HTTP_GET) { - etag_len = mio_fmt_uintmax_to_bcstr(&file_state->peer_etag[0], MIO_COUNTOF(file_state->peer_etag), st.st_mtim.tv_sec, 16, -1, '\0', MIO_NULL); - file_state->peer_etag[etag_len++] = '-'; - etag_len += mio_fmt_uintmax_to_bcstr(&file_state->peer_etag[etag_len], MIO_COUNTOF(file_state->peer_etag), st.st_mtim.tv_nsec, 16, -1, '\0', MIO_NULL); - file_state->peer_etag[etag_len++] = '-'; - etag_len += mio_fmt_uintmax_to_bcstr(&file_state->peer_etag[etag_len], MIO_COUNTOF(file_state->peer_etag) - etag_len, st.st_size, 16, -1, '\0', MIO_NULL); - file_state->peer_etag[etag_len++] = '-'; - etag_len += mio_fmt_uintmax_to_bcstr(&file_state->peer_etag[etag_len], MIO_COUNTOF(file_state->peer_etag) - etag_len, st.st_ino, 16, -1, '\0', MIO_NULL); - file_state->peer_etag[etag_len++] = '-'; - mio_fmt_uintmax_to_bcstr (&file_state->peer_etag[etag_len], MIO_COUNTOF(file_state->peer_etag) - etag_len, st.st_dev, 16, -1, '\0', MIO_NULL); + etag_len = mio_fmt_uintmax_to_bcstr(&file->peer_etag[0], MIO_COUNTOF(file->peer_etag), st.st_mtim.tv_sec, 16, -1, '\0', MIO_NULL); + file->peer_etag[etag_len++] = '-'; + etag_len += mio_fmt_uintmax_to_bcstr(&file->peer_etag[etag_len], MIO_COUNTOF(file->peer_etag), st.st_mtim.tv_nsec, 16, -1, '\0', MIO_NULL); + file->peer_etag[etag_len++] = '-'; + etag_len += mio_fmt_uintmax_to_bcstr(&file->peer_etag[etag_len], MIO_COUNTOF(file->peer_etag) - etag_len, st.st_size, 16, -1, '\0', MIO_NULL); + file->peer_etag[etag_len++] = '-'; + etag_len += mio_fmt_uintmax_to_bcstr(&file->peer_etag[etag_len], MIO_COUNTOF(file->peer_etag) - etag_len, st.st_ino, 16, -1, '\0', MIO_NULL); + file->peer_etag[etag_len++] = '-'; + mio_fmt_uintmax_to_bcstr (&file->peer_etag[etag_len], MIO_COUNTOF(file->peer_etag) - etag_len, st.st_dev, 16, -1, '\0', MIO_NULL); tmp = mio_htre_getheaderval(req, "If-None-Match"); - if (tmp && mio_comp_bcstr(file_state->peer_etag, tmp->ptr, 0) == 0) file_state->etag_match = 1; + if (tmp && mio_comp_bcstr(file->peer_etag, tmp->ptr, 0) == 0) file->etag_match = 1; } - file_state->end_offset = st.st_size; + file->end_offset = st.st_size; tmp = mio_htre_getheaderval(req, "Range"); /* TODO: support multiple ranges? */ if (tmp) @@ -592,7 +592,7 @@ static MIO_INLINE int process_range_header (file_state_t* file_state, mio_htre_t if (mio_parse_http_range_bcstr(tmp->ptr, &range) <= -1) { range_not_satisifiable: - file_state_send_final_status_to_client (file_state, 416, 1); /* 406 Requested Range Not Satisfiable */ + file_send_final_status_to_client (file, 416, 1); /* 406 Requested Range Not Satisfiable */ return -1; } @@ -601,37 +601,37 @@ static MIO_INLINE int process_range_header (file_state_t* file_state, mio_htre_t case MIO_HTTP_RANGE_PROPER: /* Range XXXX-YYYY */ if (range.to >= st.st_size) goto range_not_satisifiable; - file_state->start_offset = range.from; - file_state->end_offset = range.to; + file->start_offset = range.from; + file->end_offset = range.to; break; case MIO_HTTP_RANGE_PREFIX: /* Range: XXXX- */ if (range.from >= st.st_size) goto range_not_satisifiable; - file_state->start_offset = range.from; - file_state->end_offset = st.st_size - 1; + file->start_offset = range.from; + file->end_offset = st.st_size - 1; break; case MIO_HTTP_RANGE_SUFFIX: /* Range: -XXXX */ if (range.to >= st.st_size) goto range_not_satisifiable; - file_state->start_offset = st.st_size - range.to; - file_state->end_offset = st.st_size - 1; + file->start_offset = st.st_size - range.to; + file->end_offset = st.st_size - 1; break; } - if (file_state->start_offset > 0) - lseek(file_state->peer, file_state->start_offset, SEEK_SET); + if (file->start_offset > 0) + lseek(file->peer, file->start_offset, SEEK_SET); } else { - file_state->start_offset = 0; - file_state->end_offset = st.st_size - 1; + file->start_offset = 0; + file->end_offset = st.st_size - 1; } - file_state->cur_offset = file_state->start_offset; - file_state->total_size = st.st_size; + file->cur_offset = file->start_offset; + file->total_size = st.st_size; return 0; } @@ -640,9 +640,9 @@ static MIO_INLINE int process_range_header (file_state_t* file_state, mio_htre_t ((x) == EPERM || (x) == EACCES)? 403: 500 \ ) -static int open_peer (file_state_t* file_state, const mio_bch_t* actual_file) +static int open_peer (file_t* file, const mio_bch_t* actual_file) { - switch (file_state->req_method) + switch (file->req_method) { case MIO_HTTP_GET: case MIO_HTTP_HEAD: @@ -651,7 +651,7 @@ static int open_peer (file_state_t* file_state, const mio_bch_t* actual_file) if (access(actual_file, R_OK) == -1) { - file_state_send_final_status_to_client (file_state, ERRNO_TO_STATUS_CODE(errno), 1); /* 404 not found 403 Forbidden */ + file_send_final_status_to_client (file, ERRNO_TO_STATUS_CODE(errno), 1); /* 404 not found 403 Forbidden */ return -1; } @@ -662,11 +662,11 @@ static int open_peer (file_state_t* file_state, const mio_bch_t* actual_file) #if defined(O_LARGEFILE) flags |= O_LARGEFILE; #endif - file_state->peer = open(actual_file, flags); + file->peer = open(actual_file, flags); - if (MIO_UNLIKELY(file_state->peer <= -1)) + if (MIO_UNLIKELY(file->peer <= -1)) { - file_state_send_final_status_to_client (file_state, ERRNO_TO_STATUS_CODE(errno), 1); + file_send_final_status_to_client (file, ERRNO_TO_STATUS_CODE(errno), 1); return -1; } @@ -677,20 +677,20 @@ static int open_peer (file_state_t* file_state, const mio_bch_t* actual_file) case MIO_HTTP_PUT: case MIO_HTTP_POST: /* TOOD: this is destructive. jump to default if not allowed by flags... */ - file_state->peer = open(actual_file, O_WRONLY | O_TRUNC | O_CREAT | O_NONBLOCK | O_CLOEXEC, 0644); - if (MIO_UNLIKELY(file_state->peer <= -1)) + file->peer = open(actual_file, O_WRONLY | O_TRUNC | O_CREAT | O_NONBLOCK | O_CLOEXEC, 0644); + if (MIO_UNLIKELY(file->peer <= -1)) { - file_state_send_final_status_to_client (file_state, ERRNO_TO_STATUS_CODE(errno), 1); + file_send_final_status_to_client (file, ERRNO_TO_STATUS_CODE(errno), 1); return -1; } return 0; case MIO_HTTP_PATCH: /* TOOD: this is destructive. jump to default if not allowed by flags... */ - file_state->peer = open(actual_file, O_WRONLY | O_NONBLOCK | O_CLOEXEC, 0644); - if (MIO_UNLIKELY(file_state->peer <= -1)) + file->peer = open(actual_file, O_WRONLY | O_NONBLOCK | O_CLOEXEC, 0644); + if (MIO_UNLIKELY(file->peer <= -1)) { - file_state_send_final_status_to_client (file_state, ERRNO_TO_STATUS_CODE(errno), 1); + file_send_final_status_to_client (file, ERRNO_TO_STATUS_CODE(errno), 1); return -1; } return 0; @@ -702,64 +702,64 @@ static int open_peer (file_state_t* file_state, const mio_bch_t* actual_file) #endif } - file_state_send_final_status_to_client (file_state, 405, 1); /* 405: method not allowed */ + file_send_final_status_to_client (file, 405, 1); /* 405: method not allowed */ return -1; } -static MIO_INLINE void fadvise_on_peer (file_state_t* file_state) +static MIO_INLINE void fadvise_on_peer (file_t* file) { #if defined(HAVE_POSIX_FADVISE) - if (file_state->req_method == MIO_HTTP_GET) - posix_fadvise (file_state->peer, file_state->start_offset, file_state->end_offset - file_state->start_offset + 1, POSIX_FADV_SEQUENTIAL); + if (file->req_method == MIO_HTTP_GET) + posix_fadvise (file->peer, file->start_offset, file->end_offset - file->start_offset + 1, POSIX_FADV_SEQUENTIAL); #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, const mio_bch_t* mime_type) +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* filepath, const mio_bch_t* mime_type) { /* TODO: ETag, Last-Modified... */ mio_t* mio = htts->mio; mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(csck); - file_state_t* file_state = MIO_NULL; + file_t* file = MIO_NULL; mio_bch_t* actual_file = MIO_NULL; /* ensure that you call this function before any contents is received */ MIO_ASSERT (mio, mio_htre_getcontentlen(req) == 0); - actual_file = mio_svc_htts_dupmergepaths(htts, docroot, file); + actual_file = mio_svc_htts_dupmergepaths(htts, docroot, filepath); if (MIO_UNLIKELY(!actual_file)) goto oops; - file_state = (file_state_t*)mio_svc_htts_rsrc_make(htts, MIO_SIZEOF(*file_state), file_state_on_kill); - if (MIO_UNLIKELY(!file_state)) goto oops; + file = (file_t*)mio_svc_htts_rsrc_make(htts, MIO_SIZEOF(*file), file_on_kill); + if (MIO_UNLIKELY(!file)) goto oops; - file_state->client = cli; - file_state->sendfile_ok = mio_dev_sck_sendfileok(cli->sck); - /*file_state->num_pending_writes_to_client = 0; - file_state->num_pending_writes_to_peer = 0;*/ - file_state->req_version = *mio_htre_getversion(req); - file_state->req_method = mio_htre_getqmethodtype(req); - file_state->req_content_length_unlimited = mio_htre_getreqcontentlen(req, &file_state->req_content_length); + file->client = cli; + file->sendfile_ok = mio_dev_sck_sendfileok(cli->sck); + /*file->num_pending_writes_to_client = 0; + file->num_pending_writes_to_peer = 0;*/ + file->req_version = *mio_htre_getversion(req); + file->req_method = mio_htre_getqmethodtype(req); + file->req_content_length_unlimited = mio_htre_getreqcontentlen(req, &file->req_content_length); - file_state->client_org_on_read = csck->on_read; - file_state->client_org_on_write = csck->on_write; - file_state->client_org_on_disconnect = csck->on_disconnect; + file->client_org_on_read = csck->on_read; + file->client_org_on_write = csck->on_write; + file->client_org_on_disconnect = csck->on_disconnect; csck->on_read = file_client_on_read; csck->on_write = file_client_on_write; csck->on_disconnect = file_client_on_disconnect; MIO_ASSERT (mio, cli->rsrc == MIO_NULL); /* you must not call this function while cli->rsrc is not MIO_NULL */ - MIO_SVC_HTTS_RSRC_ATTACH (file_state, cli->rsrc); + MIO_SVC_HTTS_RSRC_ATTACH (file, cli->rsrc); - file_state->peer_tmridx = MIO_TMRIDX_INVALID; - file_state->peer = -1; + file->peer_tmridx = MIO_TMRIDX_INVALID; + file->peer = -1; - if (open_peer(file_state, actual_file) <= -1 || - process_range_header(file_state, req) <= -1) goto oops; + if (open_peer(file, actual_file) <= -1 || + process_range_header(file, req) <= -1) goto oops; - fadvise_on_peer (file_state); + fadvise_on_peer (file); #if !defined(FILE_ALLOW_UNLIMITED_REQ_CONTENT_LENGTH) - if (file_state->req_content_length_unlimited) + if (file->req_content_length_unlimited) { /* Transfer-Encoding is chunked. no content-length is known in advance. */ @@ -767,57 +767,57 @@ int mio_svc_htts_dofile (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* * option 2. send 411 Length Required immediately * option 3. set Content-Length to -1 and use EOF to indicate the end of content [Non-Standard] */ - if (file_state_send_final_status_to_client(file_state, 411, 1) <= -1) goto oops; + if (file_send_final_status_to_client(file, 411, 1) <= -1) goto oops; } #endif if (req->flags & MIO_HTRE_ATTR_EXPECT100) { if (mio_comp_http_version_numbers(&req->version, 1, 1) >= 0 && - (file_state->req_content_length_unlimited || file_state->req_content_length > 0) && - (file_state->req_method != MIO_HTTP_GET && file_state->req_method != MIO_HTTP_HEAD)) + (file->req_content_length_unlimited || file->req_content_length > 0) && + (file->req_method != MIO_HTTP_GET && file->req_method != MIO_HTTP_HEAD)) { mio_bch_t msgbuf[64]; mio_oow_t msglen; - msglen = mio_fmttobcstr(mio, msgbuf, MIO_COUNTOF(msgbuf), "HTTP/%d.%d 100 Continue\r\n\r\n", file_state->req_version.major, file_state->req_version.minor); - if (file_state_write_to_client(file_state, msgbuf, msglen) <= -1) goto oops; - file_state->ever_attempted_to_write_to_client = 0; /* reset this as it's polluted for 100 continue */ + msglen = mio_fmttobcstr(mio, msgbuf, MIO_COUNTOF(msgbuf), "HTTP/%d.%d 100 Continue\r\n\r\n", file->req_version.major, file->req_version.minor); + if (file_write_to_client(file, msgbuf, msglen) <= -1) goto oops; + file->ever_attempted_to_write_to_client = 0; /* reset this as it's polluted for 100 continue */ } } else if (req->flags & MIO_HTRE_ATTR_EXPECT) { /* 417 Expectation Failed */ - file_state_send_final_status_to_client (file_state, 417, 1); + file_send_final_status_to_client (file, 417, 1); goto oops; } #if defined(FILE_ALLOW_UNLIMITED_REQ_CONTENT_LENGTH) - if (file_state->req_content_length_unlimited) + if (file->req_content_length_unlimited) { /* change the callbacks to subscribe to contents to be uploaded */ - file_state->client_htrd_org_recbs = *mio_htrd_getrecbs(file_state->client->htrd); - file_client_htrd_recbs.peek = file_state->client_htrd_org_recbs.peek; - mio_htrd_setrecbs (file_state->client->htrd, &file_client_htrd_recbs); - file_state->client_htrd_recbs_changed = 1; + file->client_htrd_org_recbs = *mio_htrd_getrecbs(file->client->htrd); + file_client_htrd_recbs.peek = file->client_htrd_org_recbs.peek; + mio_htrd_setrecbs (file->client->htrd, &file_client_htrd_recbs); + file->client_htrd_recbs_changed = 1; } else { #endif - if (file_state->req_content_length > 0) + if (file->req_content_length > 0) { /* change the callbacks to subscribe to contents to be uploaded */ - file_state->client_htrd_org_recbs = *mio_htrd_getrecbs(file_state->client->htrd); - file_client_htrd_recbs.peek = file_state->client_htrd_org_recbs.peek; - mio_htrd_setrecbs (file_state->client->htrd, &file_client_htrd_recbs); - file_state->client_htrd_recbs_changed = 1; + file->client_htrd_org_recbs = *mio_htrd_getrecbs(file->client->htrd); + file_client_htrd_recbs.peek = file->client_htrd_org_recbs.peek; + mio_htrd_setrecbs (file->client->htrd, &file_client_htrd_recbs); + file->client_htrd_recbs_changed = 1; } else { /* no content to be uploaded from the client */ /* indicate EOF to the peer and disable input wathching from the client */ - if (file_state_write_to_peer(file_state, MIO_NULL, 0) <= -1) goto oops; - file_state_mark_over (file_state, FILE_STATE_OVER_READ_FROM_CLIENT | FILE_STATE_OVER_WRITE_TO_PEER); + if (file_write_to_peer(file, MIO_NULL, 0) <= -1) goto oops; + file_mark_over (file, FILE_OVER_READ_FROM_CLIENT | FILE_OVER_WRITE_TO_PEER); } #if defined(FILE_ALLOW_UNLIMITED_REQ_CONTENT_LENGTH) } @@ -826,22 +826,22 @@ int mio_svc_htts_dofile (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* /* this may change later if Content-Length is included in the file output */ if (req->flags & MIO_HTRE_ATTR_KEEPALIVE) { - file_state->keep_alive = 1; - file_state->res_mode_to_cli = FILE_STATE_RES_MODE_LENGTH; + file->keep_alive = 1; + file->res_mode_to_cli = FILE_RES_MODE_LENGTH; } else { - file_state->keep_alive = 0; - file_state->res_mode_to_cli = FILE_STATE_RES_MODE_CLOSE; + file->keep_alive = 0; + file->res_mode_to_cli = FILE_RES_MODE_CLOSE; } - if (file_state->req_method == MIO_HTTP_GET) + if (file->req_method == MIO_HTTP_GET) { - if (file_state->etag_match) + if (file->etag_match) { /* 304 not modified */ - if (file_state_send_final_status_to_client(file_state, 304, 0) <= -1) goto oops; - file_state_mark_over (file_state, FILE_STATE_OVER_READ_FROM_PEER | FILE_STATE_OVER_WRITE_TO_PEER); + if (file_send_final_status_to_client(file, 304, 0) <= -1) goto oops; + file_mark_over (file, FILE_OVER_READ_FROM_PEER | FILE_OVER_WRITE_TO_PEER); } else { @@ -849,30 +849,30 @@ int mio_svc_htts_dofile (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* #if defined(TCP_CORK) int tcp_cork = 1; #if defined(SOL_TCP) - mio_dev_sck_setsockopt(file_state->client->sck, SOL_TCP, TCP_CORK, &tcp_cork, MIO_SIZEOF(tcp_cork)); + mio_dev_sck_setsockopt(file->client->sck, SOL_TCP, TCP_CORK, &tcp_cork, MIO_SIZEOF(tcp_cork)); #elif defined(IPPROTO_TCP) - mio_dev_sck_setsockopt(file_state->client->sck, IPPROTO_TCP, TCP_CORK, &tcp_cork, MIO_SIZEOF(tcp_cork)); + mio_dev_sck_setsockopt(file->client->sck, IPPROTO_TCP, TCP_CORK, &tcp_cork, MIO_SIZEOF(tcp_cork)); #endif #endif - if (file_state_send_header_to_client(file_state, 200, 0, mime_type) <= -1 || - file_state_send_contents_to_client(file_state) <= -1) goto oops; + if (file_send_header_to_client(file, 200, 0, mime_type) <= -1 || + file_send_contents_to_client(file) <= -1) goto oops; } } - else if (file_state->req_method == MIO_HTTP_HEAD) + else if (file->req_method == MIO_HTTP_HEAD) { - if (file_state_send_header_to_client(file_state, 200, 0, mime_type) <= -1) goto oops; - file_state_mark_over (file_state, FILE_STATE_OVER_READ_FROM_PEER | FILE_STATE_OVER_WRITE_TO_PEER); + if (file_send_header_to_client(file, 200, 0, mime_type) <= -1) goto oops; + file_mark_over (file, FILE_OVER_READ_FROM_PEER | FILE_OVER_WRITE_TO_PEER); } - /* TODO: store current input watching state and use it when destroying the file_state data */ - if (mio_dev_sck_read(csck, !(file_state->over & FILE_STATE_OVER_READ_FROM_CLIENT)) <= -1) goto oops; + /* TODO: store current input watching state and use it when destroying the file data */ + if (mio_dev_sck_read(csck, !(file->over & FILE_OVER_READ_FROM_CLIENT)) <= -1) goto oops; mio_freemem (mio, actual_file); return 0; oops: MIO_DEBUG2 (mio, "HTTS(%p) - FAILURE in dofile - socket(%p)\n", htts, csck); - if (file_state) file_state_halt_participating_devices (file_state); + if (file) file_halt_participating_devices (file); if (actual_file) mio_freemem (mio, actual_file); return -1; } diff --git a/mio/lib/http-txt.c b/mio/lib/http-txt.c index 7fd23a9..5d1bcba 100644 --- a/mio/lib/http-txt.c +++ b/mio/lib/http-txt.c @@ -27,11 +27,11 @@ #include #include -#define TXT_STATE_OVER_READ_FROM_CLIENT (1 << 0) -#define TXT_STATE_OVER_WRITE_TO_CLIENT (1 << 1) -#define TXT_STATE_OVER_ALL (TXT_STATE_OVER_READ_FROM_CLIENT | TXT_STATE_OVER_WRITE_TO_CLIENT) +#define TXT_OVER_READ_FROM_CLIENT (1 << 0) +#define TXT_OVER_WRITE_TO_CLIENT (1 << 1) +#define TXT_OVER_ALL (TXT_OVER_READ_FROM_CLIENT | TXT_OVER_WRITE_TO_CLIENT) -struct txt_state_t +struct txt_t { MIO_SVC_HTTS_RSRC_HEADER; @@ -39,7 +39,7 @@ struct txt_state_t mio_svc_htts_cli_t* client; mio_http_version_t req_version; /* client request */ - unsigned int over: 2; /* must be large enough to accomodate TXT_STATE_OVER_ALL */ + unsigned int over: 2; /* must be large enough to accomodate TXT_OVER_ALL */ unsigned int keep_alive: 1; unsigned int req_content_length_unlimited: 1; unsigned int client_disconnected: 1; @@ -51,52 +51,52 @@ struct txt_state_t mio_dev_sck_on_disconnect_t client_org_on_disconnect; mio_htrd_recbs_t client_htrd_org_recbs; }; -typedef struct txt_state_t txt_state_t; +typedef struct txt_t txt_t; -static void txt_state_halt_participating_devices (txt_state_t* txt_state) +static void txt_halt_participating_devices (txt_t* txt) { - MIO_ASSERT (txt_state->client->htts->mio, txt_state->client != MIO_NULL); - MIO_ASSERT (txt_state->client->htts->mio, txt_state->client->sck != MIO_NULL); - MIO_DEBUG3 (txt_state->client->htts->mio, "HTTS(%p) - Halting participating devices in txt state %p(client=%p)\n", txt_state->client->htts, txt_state, txt_state->client->sck); - mio_dev_sck_halt (txt_state->client->sck); + MIO_ASSERT (txt->client->htts->mio, txt->client != MIO_NULL); + MIO_ASSERT (txt->client->htts->mio, txt->client->sck != MIO_NULL); + MIO_DEBUG3 (txt->client->htts->mio, "HTTS(%p) - Halting participating devices in txt state %p(client=%p)\n", txt->client->htts, txt, txt->client->sck); + mio_dev_sck_halt (txt->client->sck); } -static int txt_state_write_to_client (txt_state_t* txt_state, const void* data, mio_iolen_t dlen) +static int txt_write_to_client (txt_t* txt, const void* data, mio_iolen_t dlen) { - txt_state->num_pending_writes_to_client++; - if (mio_dev_sck_write(txt_state->client->sck, data, dlen, MIO_NULL, MIO_NULL) <= -1) + txt->num_pending_writes_to_client++; + if (mio_dev_sck_write(txt->client->sck, data, dlen, MIO_NULL, MIO_NULL) <= -1) { - txt_state->num_pending_writes_to_client--; + txt->num_pending_writes_to_client--; return -1; } return 0; } #if 0 -static int txt_state_writev_to_client (txt_state_t* txt_state, mio_iovec_t* iov, mio_iolen_t iovcnt) +static int txt_writev_to_client (txt_t* txt, mio_iovec_t* iov, mio_iolen_t iovcnt) { - txt_state->num_pending_writes_to_client++; - if (mio_dev_sck_writev(txt_state->client->sck, iov, iovcnt, MIO_NULL, MIO_NULL) <= -1) + txt->num_pending_writes_to_client++; + if (mio_dev_sck_writev(txt->client->sck, iov, iovcnt, MIO_NULL, MIO_NULL) <= -1) { - txt_state->num_pending_writes_to_client--; + txt->num_pending_writes_to_client--; return -1; } return 0; } #endif -static int txt_state_send_final_status_to_client (txt_state_t* txt_state, int status_code, const char* content_type, const char* content_text, int force_close) +static int txt_send_final_status_to_client (txt_t* txt, int status_code, const char* content_type, const char* content_text, int force_close) { - mio_svc_htts_cli_t* cli = txt_state->client; + mio_svc_htts_cli_t* cli = txt->client; mio_bch_t dtbuf[64]; mio_oow_t content_text_len = 0; mio_svc_htts_fmtgmtime (cli->htts, MIO_NULL, dtbuf, MIO_COUNTOF(dtbuf)); - if (!force_close) force_close = !txt_state->keep_alive; + if (!force_close) force_close = !txt->keep_alive; if (mio_becs_fmt(cli->sbuf, "HTTP/%d.%d %d %hs\r\nServer: %hs\r\nDate: %s\r\nConnection: %hs\r\n", - txt_state->req_version.major, txt_state->req_version.minor, + txt->req_version.major, txt->req_version.minor, status_code, mio_http_status_to_bcstr(status_code), cli->htts->server_name, dtbuf, (force_close? "close": "keep-alive"), @@ -109,91 +109,91 @@ static int txt_state_send_final_status_to_client (txt_state_t* txt_state, int st } if (mio_becs_fcat(cli->sbuf, "Content-Length: %zu\r\n\r\n", content_text_len) == (mio_oow_t)-1) return -1; - return (txt_state_write_to_client(txt_state, MIO_BECS_PTR(cli->sbuf), MIO_BECS_LEN(cli->sbuf)) <= -1 || - (content_text && txt_state_write_to_client(txt_state, content_text, content_text_len) <= -1) || - (force_close && txt_state_write_to_client(txt_state, MIO_NULL, 0) <= -1))? -1: 0; + return (txt_write_to_client(txt, MIO_BECS_PTR(cli->sbuf), MIO_BECS_LEN(cli->sbuf)) <= -1 || + (content_text && txt_write_to_client(txt, content_text, content_text_len) <= -1) || + (force_close && txt_write_to_client(txt, MIO_NULL, 0) <= -1))? -1: 0; } -static MIO_INLINE void txt_state_mark_over (txt_state_t* txt_state, int over_bits) +static MIO_INLINE void txt_mark_over (txt_t* txt, int over_bits) { unsigned int old_over; - old_over = txt_state->over; - txt_state->over |= over_bits; + old_over = txt->over; + txt->over |= over_bits; - MIO_DEBUG4 (txt_state->htts->mio, "HTTS(%p) - client=%p new-bits=%x over=%x\n", txt_state->htts, txt_state->client->sck, (int)over_bits, (int)txt_state->over); + MIO_DEBUG4 (txt->htts->mio, "HTTS(%p) - client=%p new-bits=%x over=%x\n", txt->htts, txt->client->sck, (int)over_bits, (int)txt->over); - if (!(old_over & TXT_STATE_OVER_READ_FROM_CLIENT) && (txt_state->over & TXT_STATE_OVER_READ_FROM_CLIENT)) + if (!(old_over & TXT_OVER_READ_FROM_CLIENT) && (txt->over & TXT_OVER_READ_FROM_CLIENT)) { - if (mio_dev_sck_read(txt_state->client->sck, 0) <= -1) + if (mio_dev_sck_read(txt->client->sck, 0) <= -1) { - MIO_DEBUG2 (txt_state->htts->mio, "HTTS(%p) - halting client(%p) for failure to disable input watching\n", txt_state->htts, txt_state->client->sck); - mio_dev_sck_halt (txt_state->client->sck); + MIO_DEBUG2 (txt->htts->mio, "HTTS(%p) - halting client(%p) for failure to disable input watching\n", txt->htts, txt->client->sck); + mio_dev_sck_halt (txt->client->sck); } } - if (old_over != TXT_STATE_OVER_ALL && txt_state->over == TXT_STATE_OVER_ALL) + if (old_over != TXT_OVER_ALL && txt->over == TXT_OVER_ALL) { /* ready to stop */ - if (txt_state->keep_alive) + if (txt->keep_alive) { - /* how to arrange to delete this txt_state object and put the socket back to the normal waiting state??? */ - MIO_ASSERT (txt_state->htts->mio, txt_state->client->rsrc == (mio_svc_htts_rsrc_t*)txt_state); + /* how to arrange to delete this txt object and put the socket back to the normal waiting state??? */ + MIO_ASSERT (txt->htts->mio, txt->client->rsrc == (mio_svc_htts_rsrc_t*)txt); -printf ("DETACHING FROM THE MAIN CLIENT RSRC... state -> %p\n", txt_state->client->rsrc); - MIO_SVC_HTTS_RSRC_DETACH (txt_state->client->rsrc); - /* txt_state must not be access from here down as it could have been destroyed */ +printf ("DETACHING FROM THE MAIN CLIENT RSRC... state -> %p\n", txt->client->rsrc); + MIO_SVC_HTTS_RSRC_DETACH (txt->client->rsrc); + /* txt must not be access from here down as it could have been destroyed */ } else { - MIO_DEBUG2 (txt_state->htts->mio, "HTTS(%p) - halting client(%p) for no keep-alive\n", txt_state->htts, txt_state->client->sck); - mio_dev_sck_shutdown (txt_state->client->sck, MIO_DEV_SCK_SHUTDOWN_WRITE); - mio_dev_sck_halt (txt_state->client->sck); + MIO_DEBUG2 (txt->htts->mio, "HTTS(%p) - halting client(%p) for no keep-alive\n", txt->htts, txt->client->sck); + mio_dev_sck_shutdown (txt->client->sck, MIO_DEV_SCK_SHUTDOWN_WRITE); + mio_dev_sck_halt (txt->client->sck); } } } -static void txt_state_on_kill (txt_state_t* txt_state) +static void txt_on_kill (txt_t* txt) { - mio_t* mio = txt_state->htts->mio; + mio_t* mio = txt->htts->mio; - MIO_DEBUG2 (mio, "HTTS(%p) - killing txt_state client(%p)\n", txt_state->htts, txt_state->client->sck); + MIO_DEBUG2 (mio, "HTTS(%p) - killing txt client(%p)\n", txt->htts, txt->client->sck); - if (txt_state->client_org_on_read) + if (txt->client_org_on_read) { - txt_state->client->sck->on_read = txt_state->client_org_on_read; - txt_state->client_org_on_read = MIO_NULL; + txt->client->sck->on_read = txt->client_org_on_read; + txt->client_org_on_read = MIO_NULL; } - if (txt_state->client_org_on_write) + if (txt->client_org_on_write) { - txt_state->client->sck->on_write = txt_state->client_org_on_write; - txt_state->client_org_on_write = MIO_NULL; + txt->client->sck->on_write = txt->client_org_on_write; + txt->client_org_on_write = MIO_NULL; } - if (txt_state->client_org_on_disconnect) + if (txt->client_org_on_disconnect) { - txt_state->client->sck->on_disconnect = txt_state->client_org_on_disconnect; - txt_state->client_org_on_disconnect = MIO_NULL; + txt->client->sck->on_disconnect = txt->client_org_on_disconnect; + txt->client_org_on_disconnect = MIO_NULL; } - if (txt_state->client_htrd_recbs_changed) + if (txt->client_htrd_recbs_changed) { /* restore the callbacks */ - mio_htrd_setrecbs (txt_state->client->htrd, &txt_state->client_htrd_org_recbs); + mio_htrd_setrecbs (txt->client->htrd, &txt->client_htrd_org_recbs); } - if (!txt_state->client_disconnected) + if (!txt->client_disconnected) { -/*printf ("ENABLING INPUT WATCHING on CLIENT %p. \n", txt_state->client->sck);*/ - if (!txt_state->keep_alive || mio_dev_sck_read(txt_state->client->sck, 1) <= -1) +/*printf ("ENABLING INPUT WATCHING on CLIENT %p. \n", txt->client->sck);*/ + if (!txt->keep_alive || mio_dev_sck_read(txt->client->sck, 1) <= -1) { - MIO_DEBUG2 (mio, "HTTS(%p) - halting client(%p) for failure to enable input watching\n", txt_state->htts, txt_state->client->sck); - mio_dev_sck_halt (txt_state->client->sck); + MIO_DEBUG2 (mio, "HTTS(%p) - halting client(%p) for failure to enable input watching\n", txt->htts, txt->client->sck); + mio_dev_sck_halt (txt->client->sck); } } -/*printf ("**** TXT_STATE_ON_KILL DONE\n");*/ +/*printf ("**** TXT_ON_KILL DONE\n");*/ } static int txt_client_htrd_poke (mio_htrd_t* htrd, mio_htre_t* req) @@ -202,11 +202,11 @@ static int txt_client_htrd_poke (mio_htrd_t* htrd, mio_htre_t* req) mio_svc_htts_cli_htrd_xtn_t* htrdxtn = (mio_svc_htts_cli_htrd_xtn_t*)mio_htrd_getxtn(htrd); mio_dev_sck_t* sck = htrdxtn->sck; mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(sck); - txt_state_t* txt_state = (txt_state_t*)cli->rsrc; + txt_t* txt = (txt_t*)cli->rsrc; printf (">> CLIENT REQUEST COMPLETED\n"); - txt_state_mark_over (txt_state, TXT_STATE_OVER_READ_FROM_CLIENT); + txt_mark_over (txt, TXT_OVER_READ_FROM_CLIENT); return 0; } @@ -226,16 +226,16 @@ static mio_htrd_recbs_t txt_client_htrd_recbs = static void txt_client_on_disconnect (mio_dev_sck_t* sck) { mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(sck); - txt_state_t* txt_state = (txt_state_t*)cli->rsrc; - txt_state->client_disconnected = 1; - txt_state->client_org_on_disconnect (sck); + txt_t* txt = (txt_t*)cli->rsrc; + txt->client_disconnected = 1; + txt->client_org_on_disconnect (sck); } static int txt_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_svc_htts_cli_t* cli = mio_dev_sck_getxtn(sck); - txt_state_t* txt_state = (txt_state_t*)cli->rsrc; + txt_t* txt = (txt_t*)cli->rsrc; MIO_ASSERT (mio, sck == cli->sck); @@ -249,18 +249,18 @@ static int txt_client_on_read (mio_dev_sck_t* sck, const void* buf, mio_iolen_t if (len == 0) { /* EOF on the client side. arrange to close */ - MIO_DEBUG3 (mio, "HTTPS(%p) - EOF from client %p(hnd=%d)\n", txt_state->client->htts, sck, (int)sck->hnd); + MIO_DEBUG3 (mio, "HTTPS(%p) - EOF from client %p(hnd=%d)\n", txt->client->htts, sck, (int)sck->hnd); - if (!(txt_state->over & TXT_STATE_OVER_READ_FROM_CLIENT)) /* if this is true, EOF is received without txt_client_htrd_poke() */ + if (!(txt->over & TXT_OVER_READ_FROM_CLIENT)) /* if this is true, EOF is received without txt_client_htrd_poke() */ { - txt_state_mark_over (txt_state, TXT_STATE_OVER_READ_FROM_CLIENT); + txt_mark_over (txt, TXT_OVER_READ_FROM_CLIENT); } } else { mio_oow_t rem; - MIO_ASSERT (mio, !(txt_state->over & TXT_STATE_OVER_READ_FROM_CLIENT)); + MIO_ASSERT (mio, !(txt->over & TXT_OVER_READ_FROM_CLIENT)); if (mio_htrd_feed(cli->htrd, buf, len, &rem) <= -1) goto oops; @@ -274,7 +274,7 @@ printf ("UUUUUUUUUUUUUUUUUUUUUUUUUUGGGGGHHHHHHHHHHHH .......... TXT CLIENT GIVIN return 0; oops: - txt_state_halt_participating_devices (txt_state); + txt_halt_participating_devices (txt); return 0; } @@ -282,7 +282,7 @@ static int txt_client_on_write (mio_dev_sck_t* sck, mio_iolen_t wrlen, void* wrc { mio_t* mio = sck->mio; mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(sck); - txt_state_t* txt_state = (txt_state_t*)cli->rsrc; + txt_t* txt = (txt_t*)cli->rsrc; if (wrlen <= -1) { @@ -293,28 +293,28 @@ static int txt_client_on_write (mio_dev_sck_t* sck, mio_iolen_t wrlen, void* wrc if (wrlen == 0) { /* if the connect is keep-alive, this part may not be called */ - txt_state->num_pending_writes_to_client--; - MIO_ASSERT (mio, txt_state->num_pending_writes_to_client == 0); - MIO_DEBUG3 (mio, "HTTS(%p) - indicated EOF to client %p(%d)\n", txt_state->client->htts, sck, (int)sck->hnd); + txt->num_pending_writes_to_client--; + MIO_ASSERT (mio, txt->num_pending_writes_to_client == 0); + MIO_DEBUG3 (mio, "HTTS(%p) - indicated EOF to client %p(%d)\n", txt->client->htts, sck, (int)sck->hnd); /* 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. * i don't need to enable input watching on the peer side */ - txt_state_mark_over (txt_state, TXT_STATE_OVER_WRITE_TO_CLIENT); + txt_mark_over (txt, TXT_OVER_WRITE_TO_CLIENT); } else { - MIO_ASSERT (mio, txt_state->num_pending_writes_to_client > 0); - txt_state->num_pending_writes_to_client--; - if (txt_state->num_pending_writes_to_client <= 0) + MIO_ASSERT (mio, txt->num_pending_writes_to_client > 0); + txt->num_pending_writes_to_client--; + if (txt->num_pending_writes_to_client <= 0) { - txt_state_mark_over (txt_state, TXT_STATE_OVER_WRITE_TO_CLIENT); + txt_mark_over (txt, TXT_OVER_WRITE_TO_CLIENT); } } return 0; oops: - txt_state_halt_participating_devices (txt_state); + txt_halt_participating_devices (txt); return 0; } @@ -322,28 +322,28 @@ int mio_svc_htts_dotxt (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* r { mio_t* mio = htts->mio; mio_svc_htts_cli_t* cli = mio_dev_sck_getxtn(csck); - txt_state_t* txt_state = MIO_NULL; + txt_t* txt = MIO_NULL; /* ensure that you call this function before any contents is received */ MIO_ASSERT (mio, mio_htre_getcontentlen(req) == 0); - txt_state = (txt_state_t*)mio_svc_htts_rsrc_make(htts, MIO_SIZEOF(*txt_state), txt_state_on_kill); - if (MIO_UNLIKELY(!txt_state)) goto oops; + txt = (txt_t*)mio_svc_htts_rsrc_make(htts, MIO_SIZEOF(*txt), txt_on_kill); + if (MIO_UNLIKELY(!txt)) goto oops; - txt_state->client = cli; - /*txt_state->num_pending_writes_to_client = 0;*/ - txt_state->req_version = *mio_htre_getversion(req); - txt_state->req_content_length_unlimited = mio_htre_getreqcontentlen(req, &txt_state->req_content_length); + txt->client = cli; + /*txt->num_pending_writes_to_client = 0;*/ + txt->req_version = *mio_htre_getversion(req); + txt->req_content_length_unlimited = mio_htre_getreqcontentlen(req, &txt->req_content_length); - txt_state->client_org_on_read = csck->on_read; - txt_state->client_org_on_write = csck->on_write; - txt_state->client_org_on_disconnect = csck->on_disconnect; + txt->client_org_on_read = csck->on_read; + txt->client_org_on_write = csck->on_write; + txt->client_org_on_disconnect = csck->on_disconnect; csck->on_read = txt_client_on_read; csck->on_write = txt_client_on_write; csck->on_disconnect = txt_client_on_disconnect; MIO_ASSERT (mio, cli->rsrc == MIO_NULL); - MIO_SVC_HTTS_RSRC_ATTACH (txt_state, cli->rsrc); + MIO_SVC_HTTS_RSRC_ATTACH (txt, cli->rsrc); if (req->flags & MIO_HTRE_ATTR_EXPECT100) { @@ -352,36 +352,36 @@ int mio_svc_htts_dotxt (mio_svc_htts_t* htts, mio_dev_sck_t* csck, mio_htre_t* r else if (req->flags & MIO_HTRE_ATTR_EXPECT) { /* 417 Expectation Failed */ - txt_state_send_final_status_to_client(txt_state, 417, MIO_NULL, MIO_NULL, 1); + txt_send_final_status_to_client(txt, 417, MIO_NULL, MIO_NULL, 1); goto oops; } - if (txt_state->req_content_length_unlimited || txt_state->req_content_length > 0) + if (txt->req_content_length_unlimited || txt->req_content_length > 0) { /* change the callbacks to subscribe to contents to be uploaded */ - txt_state->client_htrd_org_recbs = *mio_htrd_getrecbs(txt_state->client->htrd); - txt_client_htrd_recbs.peek = txt_state->client_htrd_org_recbs.peek; - mio_htrd_setrecbs (txt_state->client->htrd, &txt_client_htrd_recbs); - txt_state->client_htrd_recbs_changed = 1; + txt->client_htrd_org_recbs = *mio_htrd_getrecbs(txt->client->htrd); + txt_client_htrd_recbs.peek = txt->client_htrd_org_recbs.peek; + mio_htrd_setrecbs (txt->client->htrd, &txt_client_htrd_recbs); + txt->client_htrd_recbs_changed = 1; } else { /* no content to be uploaded from the client */ /* indicate EOF to the peer and disable input wathching from the client */ - txt_state_mark_over (txt_state, TXT_STATE_OVER_READ_FROM_CLIENT); + txt_mark_over (txt, TXT_OVER_READ_FROM_CLIENT); } /* this may change later if Content-Length is included in the txt output */ - txt_state->keep_alive = !!(req->flags & MIO_HTRE_ATTR_KEEPALIVE); + txt->keep_alive = !!(req->flags & MIO_HTRE_ATTR_KEEPALIVE); - /* TODO: store current input watching state and use it when destroying the txt_state data */ - if (mio_dev_sck_read(csck, !(txt_state->over & TXT_STATE_OVER_READ_FROM_CLIENT)) <= -1) goto oops; + /* TODO: store current input watching state and use it when destroying the txt data */ + if (mio_dev_sck_read(csck, !(txt->over & TXT_OVER_READ_FROM_CLIENT)) <= -1) goto oops; - if (txt_state_send_final_status_to_client(txt_state, status_code, content_type, content_text, 0) <= -1) goto oops; + if (txt_send_final_status_to_client(txt, status_code, content_type, content_text, 0) <= -1) goto oops; return 0; oops: MIO_DEBUG2 (mio, "HTTS(%p) - FAILURE in dotxt - socket(%p)\n", htts, csck); - if (txt_state) txt_state_halt_participating_devices (txt_state); + if (txt) txt_halt_participating_devices (txt); return -1; } diff --git a/mio/lib/mio-http.h b/mio/lib/mio-http.h index 7a23ea4..699eeaf 100644 --- a/mio/lib/mio-http.h +++ b/mio/lib/mio-http.h @@ -288,7 +288,7 @@ MIO_EXPORT int mio_svc_htts_dofile ( mio_dev_sck_t* csck, mio_htre_t* req, const mio_bch_t* docroot, - const mio_bch_t* file, + const mio_bch_t* filepath, const mio_bch_t* mime_type );