[MEDIUM] stats: make HTTP stats use an I/O handler
Doing this, we can remove the last BF_HIJACK user and remove
produce_content(). s->data_source could also be removed but
it is currently used to detect if the stats or a server was
used.
diff --git a/src/dumpstats.c b/src/dumpstats.c
index 14cc519..e8eef21 100644
--- a/src/dumpstats.c
+++ b/src/dumpstats.c
@@ -587,7 +587,6 @@
/* skip the disabled proxies and non-networked ones */
if (px->state != PR_STSTOPPED &&
(px->cap & (PR_CAP_FE | PR_CAP_BE))) {
- rep->flags |= BF_READ_PARTIAL; /* remove this once stats_dump_proxy uses buffer_feed */
if (stats_dump_proxy(s, px, NULL) == 0)
return 0;
}
@@ -616,6 +615,57 @@
}
+/* This I/O handler runs as an applet embedded in a stream interface. It is
+ * used to send HTTP stats over a TCP socket. The mechanism is very simple.
+ * si->st0 becomes non-zero once the transfer is finished. The handler
+ * automatically unregisters itself once transfer is complete.
+ */
+void http_stats_io_handler(struct stream_interface *si)
+{
+ struct session *s = si->private;
+ struct buffer *req = si->ob;
+ struct buffer *res = si->ib;
+
+ if (unlikely(si->state == SI_ST_DIS || si->state == SI_ST_CLO))
+ goto out;
+
+ /* check that the output is not closed */
+ if (res->flags & (BF_SHUTW|BF_SHUTW_NOW))
+ si->st0 = 1;
+
+ if (!si->st0) {
+ if (stats_dump_http(s, res, s->be->uri_auth)) {
+ si->st0 = 1;
+ si->shutw(si);
+ } else {
+ /* buffer full */
+ si->flags |= SI_FL_WAIT_ROOM;
+ }
+ }
+
+ if ((res->flags & BF_SHUTR) && (si->state == SI_ST_EST))
+ si->shutw(si);
+
+ if ((req->flags & BF_SHUTW) && (si->state == SI_ST_EST) && si->st0) {
+ si->shutr(si);
+ res->flags |= BF_READ_NULL;
+ }
+
+ /* update all other flags and resync with the other side */
+ si->update(si);
+
+ /* we don't want to expire timeouts while we're processing requests */
+ si->ib->rex = TICK_ETERNITY;
+ si->ob->wex = TICK_ETERNITY;
+
+ out:
+ if (unlikely(si->state == SI_ST_DIS || si->state == SI_ST_CLO)) {
+ /* check that we have released everything then unregister */
+ stream_int_unregister_handler(si);
+ }
+}
+
+
/*
* Produces statistics data for the session <s>. Expects to be called with
* client socket shut down on input. It stops by itself by unsetting the
@@ -650,11 +700,9 @@
chunk_printf(&msg, "\r\n");
s->txn.status = 200;
- if (buffer_write_chunk(rep, &msg) >= 0)
+ if (buffer_feed_chunk(rep, &msg) >= 0)
return 0;
- msg.len = 0;
-
if (!(s->flags & SN_ERR_MASK)) // this is not really an error but it is
s->flags |= SN_ERR_PRXCOND; // to mark that it comes from the proxy
if (!(s->flags & SN_FINST_MASK))
@@ -663,7 +711,6 @@
if (s->txn.meth == HTTP_METH_HEAD) {
/* that's all we return in case of HEAD request */
s->data_state = DATA_ST_FIN;
- buffer_stop_hijack(rep);
return 1;
}
@@ -754,7 +801,7 @@
} else {
print_csv_header(&msg);
}
- if (buffer_write_chunk(rep, &msg) >= 0)
+ if (buffer_feed_chunk(rep, &msg) >= 0)
return 0;
s->data_state = DATA_ST_INFO;
@@ -866,7 +913,7 @@
""
);
- if (buffer_write_chunk(rep, &msg) >= 0)
+ if (buffer_feed_chunk(rep, &msg) >= 0)
return 0;
}
@@ -895,7 +942,7 @@
case DATA_ST_END:
if (!(s->data_ctx.stats.flags & STAT_FMT_CSV)) {
chunk_printf(&msg, "</body></html>\n");
- if (buffer_write_chunk(rep, &msg) >= 0)
+ if (buffer_feed_chunk(rep, &msg) >= 0)
return 0;
}
@@ -903,12 +950,11 @@
/* fall through */
case DATA_ST_FIN:
- buffer_stop_hijack(rep);
return 1;
default:
/* unknown state ! */
- buffer_stop_hijack(rep);
+ s->data_state = DATA_ST_FIN;
return -1;
}
}
@@ -994,7 +1040,7 @@
px->id,
px->desc ? "desc" : "empty", px->desc ? px->desc : "");
- if (buffer_write_chunk(rep, &msg) >= 0)
+ if (buffer_feed_chunk(rep, &msg) >= 0)
return 0;
}
@@ -1075,7 +1121,7 @@
px->fe_sps_lim, px->fe_sps_max);
}
- if (buffer_write_chunk(rep, &msg) >= 0)
+ if (buffer_feed_chunk(rep, &msg) >= 0)
return 0;
}
@@ -1339,7 +1385,7 @@
/* finish with EOL */
chunk_printf(&msg, "\n");
}
- if (buffer_write_chunk(rep, &msg) >= 0)
+ if (buffer_feed_chunk(rep, &msg) >= 0)
return 0;
} /* for sv */
@@ -1452,7 +1498,7 @@
read_freq_ctr(&px->be_sess_per_sec),
px->be_sps_max);
}
- if (buffer_write_chunk(rep, &msg) >= 0)
+ if (buffer_feed_chunk(rep, &msg) >= 0)
return 0;
}
@@ -1463,7 +1509,7 @@
if (!(s->data_ctx.stats.flags & STAT_FMT_CSV)) {
chunk_printf(&msg, "</table><p>\n");
- if (buffer_write_chunk(rep, &msg) >= 0)
+ if (buffer_feed_chunk(rep, &msg) >= 0)
return 0;
}