diff --git a/lib/hcl-c.c b/lib/hcl-c.c index f6c9277..a330f06 100644 --- a/lib/hcl-c.c +++ b/lib/hcl-c.c @@ -666,10 +666,11 @@ static int feed_reply_data (hcl_client_t* client, const hcl_bch_t* data, hcl_oow } ptr += taken; - client->rep.u.length_bounded_data.tally = taken; + client->rep.u.length_bounded_data.tally += taken; if (taken == capa) { /* read all data. no more */ + HCL_ASSERT (client->dummy_hcl, client->rep.u.length_bounded_data.max == client->rep.u.length_bounded_data.tally); client->state = HCL_CLIENT_STATE_START; if (client->prim.end_reply(client, HCL_CLIENT_END_REPLY_STATE_OK) <= -1) goto oops; } diff --git a/lib/hcl-s.c b/lib/hcl-s.c index 690c9b8..9e91b46 100644 --- a/lib/hcl-s.c +++ b/lib/hcl-s.c @@ -456,30 +456,40 @@ static HCL_INLINE int read_input (hcl_t* hcl, hcl_ioinarg_t* arg) worker_hcl_xtn_t* xtn = (worker_hcl_xtn_t*)hcl_getxtn(hcl); bb_t* bb; hcl_oow_t bcslen, ucslen, remlen; + hcl_server_worker_t* worker; int x; bb = (bb_t*)arg->handle; HCL_ASSERT (hcl, bb != HCL_NULL && bb->fd >= 0); - if (bb->fd == xtn->proto->worker->sck) + worker = xtn->proto->worker; + + if (bb->fd == worker->sck) { ssize_t x; + hcl_server_t* server; + + server = worker->server; start_over: while (1) { int n; struct pollfd pfd; - - if (xtn->proto->worker->server->stopreq) + int tmout, actual_tmout; + + if (server->stopreq) { hcl_seterrbfmt (hcl, HCL_EGENERIC, "stop requested"); return -1; } + tmout = HCL_SECNSEC_TO_MSEC(server->cfg.worker_idle_timeout.sec, server->cfg.worker_idle_timeout.nsec); + actual_tmout = (tmout <= 0)? 10000: tmout; + pfd.fd = bb->fd; pfd.events = POLLIN | POLLERR; - n = poll(&pfd, 1, 10000); /* TOOD: adjust this interval base on the worker_idle_timeout? */ + n = poll(&pfd, 1, actual_tmout); if (n <= -1) { if (errno == EINTR) goto start_over; @@ -488,7 +498,12 @@ static HCL_INLINE int read_input (hcl_t* hcl, hcl_ioinarg_t* arg) } else if (n >= 1) break; -/* TOOD: idle timeout check - compute idling time and check it against server->cfg.worker_idle_timeout */ + /* timed out - no activity on the pfd */ + if (tmout > 0) + { + hcl_seterrbfmt (hcl, HCL_EGENERIC, "no activity on the worker socket %d", worker->sck); + return -1; + } } x = recv(bb->fd, &bb->buf[bb->len], HCL_COUNTOF(bb->buf) - bb->len, 0); diff --git a/lib/main-c.c b/lib/main-c.c index cac48c4..0a4006e 100644 --- a/lib/main-c.c +++ b/lib/main-c.c @@ -501,7 +501,7 @@ static int feed_data (hcl_client_t* client, const void* ptr, hcl_oow_t len) /* ========================================================================= */ -static int handle_request (hcl_client_t* client, const char* ipaddr, const char* script) +static int handle_request (hcl_client_t* client, const char* ipaddr, const char* script, int shut_wr_after_req) { hcl_sckaddr_t sckaddr; hcl_scklen_t scklen; @@ -576,6 +576,8 @@ static int handle_request (hcl_client_t* client, const char* ipaddr, const char* iov[index].iov_len -= nwritten; } + if (shut_wr_after_req) shutdown (sck, SHUT_WR); + client_xtn->data_length = 0; client_xtn->reply_count = 0; @@ -583,7 +585,7 @@ static int handle_request (hcl_client_t* client, const char* ipaddr, const char* avail = 0; while (client_xtn->reply_count == 0) { - n = read(sck, &buf[avail], HCL_SIZEOF(buf) - avail); /* switch to recv */ + n = recv(sck, &buf[avail], HCL_SIZEOF(buf) - avail, 0); if (n <= -1) { fprintf (stderr, "Unable to read from %d - %s\n", sck, strerror(n)); @@ -601,7 +603,11 @@ static int handle_request (hcl_client_t* client, const char* ipaddr, const char* avail += n;; x = hcl_client_feed(client, buf, avail, &used); - if (x <= -1) goto oops; + if (x <= -1) + { + fprintf (stderr, "Client error [%d]\n", hcl_client_geterrnum(client)); + goto oops; + } avail -= used; if (avail > 0) memmove (&buf[0], &buf[used], avail); @@ -622,6 +628,7 @@ int main (int argc, char* argv[]) static hcl_bopt_lng_t lopt[] = { { ":log", 'l' }, + { "shutwr", '\0' }, { HCL_NULL, '\0' } }; static hcl_bopt_t opt = @@ -635,14 +642,14 @@ int main (int argc, char* argv[]) hcl_client_prim_t client_prim; int n; const char* logopt = HCL_NULL; + int shut_wr_after_req = 0; setlocale (LC_ALL, ""); - if (argc < 2) { print_usage: - fprintf (stderr, "Usage: %s bind-address:port script-to-run\n", argv[0]); + fprintf (stderr, "Usage: %s [-l/--log log-options] [--shutwr] bind-address:port script-to-run\n", argv[0]); return -1; } @@ -655,7 +662,14 @@ int main (int argc, char* argv[]) break; case '\0': - goto print_usage; + if (hcl_compbcstr(opt.lngopt, "shutwr") == 0) + { + shut_wr_after_req = 1; + } + else + { + goto print_usage; + } break; case ':': @@ -706,18 +720,12 @@ int main (int argc, char* argv[]) set_signal (SIGINT, handle_sigint); set_signal_to_ignore (SIGPIPE); - - n = handle_request (client, argv[opt.ind], argv[opt.ind + 1]); + n = handle_request (client, argv[opt.ind], argv[opt.ind + 1], shut_wr_after_req); set_signal_to_default (SIGINT); set_signal_to_default (SIGPIPE); g_client = NULL; - if (n <= -1) - { - hcl_client_logbfmt (client, HCL_LOG_APP | HCL_LOG_FATAL, "client error[%d] - %js\n", hcl_client_geterrnum(client), hcl_client_geterrmsg(client)); - } - if (xtn->logfd >= 0) { close (xtn->logfd);