[MAJOR] completely separate HTTP and TCP states on the request path
For the first time, HTTP and TCP are not merged anymore. All request
processing has moved to process_request while the TCP processing of
the frontend remains in process_cli. The code is a lot cleaner,
simpler, smaller (1%) and slightly faster (1% too).
Right now, the HTTP state machine cannot easily command the TCP
state machine, but it does not cause that many difficulties.
The response processing has not yet been extracted, and the unix-stream
state machines have to be broken down that way too.
The CL_STDATA, CL_STSHUTR and CL_STSHUTW states still exist and are
exactly the sames. They will have to be all merged into CL_STDATA
once the work has stabilized. It is also possible that this single
state will disappear in favor of just buffer flags.
diff --git a/src/client.c b/src/client.c
index cbe5f11..f5d6bb9 100644
--- a/src/client.c
+++ b/src/client.c
@@ -352,6 +352,15 @@
s->rep->wto = s->fe->timeout.client;
s->rep->cto = TICK_ETERNITY;
+ s->req->rex = TICK_ETERNITY;
+ s->req->wex = TICK_ETERNITY;
+ s->req->cex = TICK_ETERNITY;
+ s->rep->rex = TICK_ETERNITY;
+ s->rep->wex = TICK_ETERNITY;
+ s->txn.exp = TICK_ETERNITY;
+ s->inspect_exp = TICK_ETERNITY;
+ t->expire = TICK_ETERNITY;
+
fd_insert(cfd);
fdtab[cfd].owner = t;
fdtab[cfd].listener = l;
@@ -371,46 +380,21 @@
*/
struct chunk msg = { .str = "HTTP/1.0 200 OK\r\n\r\n", .len = 19 };
client_retnclose(s, &msg); /* forge a 200 response */
+ t->expire = s->rep->wex;
}
else if (p->mode == PR_MODE_HEALTH) { /* health check mode, no client reading */
struct chunk msg = { .str = "OK\n", .len = 3 };
client_retnclose(s, &msg); /* forge an "OK" response */
+ t->expire = s->rep->wex;
}
else {
EV_FD_SET(cfd, DIR_RD);
}
- s->req->rex = TICK_ETERNITY;
- s->req->wex = TICK_ETERNITY;
- s->req->cex = TICK_ETERNITY;
- s->rep->rex = TICK_ETERNITY;
- s->rep->wex = TICK_ETERNITY;
- s->txn.exp = TICK_ETERNITY;
- s->inspect_exp = TICK_ETERNITY;
- t->expire = TICK_ETERNITY;
-
- if (s->fe->timeout.client) {
- if (EV_FD_ISSET(cfd, DIR_RD)) {
- s->req->rex = tick_add(now_ms, s->fe->timeout.client);
- t->expire = s->req->rex;
- }
- if (EV_FD_ISSET(cfd, DIR_WR)) {
- s->rep->wex = tick_add(now_ms, s->fe->timeout.client);
- t->expire = s->rep->wex;
- }
- }
-
- if (s->analysis & AN_REQ_ANY) {
- if (s->analysis & AN_REQ_INSPECT) {
- s->inspect_exp = tick_add_ifset(now_ms, s->fe->tcp_req.inspect_delay);
- t->expire = tick_first(t->expire, s->inspect_exp);
- }
- else if (s->analysis & AN_REQ_HTTP_HDR) {
- s->txn.exp = tick_add_ifset(now_ms, s->fe->timeout.httpreq);
- t->expire = tick_first(t->expire, s->txn.exp);
- }
- }
-
+ /* it is important not to call the wakeup function directly but to
+ * pass through task_wakeup(), because this one knows how to apply
+ * priorities to tasks.
+ */
if (p->mode != PR_MODE_HEALTH)
task_wakeup(t);