[MINOR] stats_dump_errors_to_buffer: use buffer_feed_chunk()
We can simplify the code in the stats functions using buffer_feed_chunk()
instead of buffer_write_chunk(). Let's start with this function. This
patch also fixed an issue where we could dump past the end of the capture
buffer if it is shorter than the captured request.
diff --git a/include/proto/dumpstats.h b/include/proto/dumpstats.h
index 7a92c98..4dd9e34 100644
--- a/include/proto/dumpstats.h
+++ b/include/proto/dumpstats.h
@@ -51,7 +51,7 @@
int stats_dump_http(struct session *s, struct buffer *rep, struct uri_auth *uri);
int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri);
void stats_dump_sess_to_buffer(struct session *s, struct buffer *rep);
-void stats_dump_errors_to_buffer(struct session *s, struct buffer *rep);
+int stats_dump_errors_to_buffer(struct session *s, struct buffer *rep);
#endif /* _PROTO_DUMPSTATS_H */
diff --git a/src/dumpstats.c b/src/dumpstats.c
index 8b95933..6c8c97b 100644
--- a/src/dumpstats.c
+++ b/src/dumpstats.c
@@ -429,9 +429,7 @@
si->st0 = 1; // end of command, send prompt
break;
case 5: /* errors dump */
- stats_dump_errors_to_buffer(s, res);
- si->ib->flags |= BF_READ_PARTIAL; /* remove this once we use buffer_feed */
- if (s->ana_state == STATS_ST_CLOSE)
+ if (stats_dump_errors_to_buffer(s, res))
si->st0 = 1; // end of command, send prompt
break;
default: /* abnormal state or lack of space for prompt */
@@ -1738,7 +1736,7 @@
chunk_printf(out, " %05d%c ", ptr, (ptr == *line) ? ' ' : '+');
- while (ptr < err->len) {
+ while (ptr < err->len && ptr < sizeof(err->buf)) {
c = err->buf[ptr];
if (isprint(c) && isascii(c) && c != '\\') {
if (out->len > end - 2)
@@ -1780,22 +1778,15 @@
* It dumps the errors logged in proxies onto the output buffer <rep>.
* Expects to be called with client socket shut down on input.
* s->data_ctx must have been zeroed first, and the flags properly set.
- * It automatically clears the HIJACK bit from the response buffer.
+ * It returns 0 as long as it does not complete, non-zero upon completion.
*/
-void stats_dump_errors_to_buffer(struct session *s, struct buffer *rep)
+int stats_dump_errors_to_buffer(struct session *s, struct buffer *rep)
{
extern const char *monthname[12];
struct chunk msg;
- if (unlikely(rep->flags & (BF_WRITE_ERROR|BF_SHUTW))) {
- s->data_state = DATA_ST_FIN;
- buffer_stop_hijack(rep);
- s->ana_state = STATS_ST_CLOSE;
- return;
- }
-
- if (s->ana_state != STATS_ST_REP)
- return;
+ if (unlikely(rep->flags & (BF_WRITE_ERROR|BF_SHUTW)))
+ return 1;
chunk_init(&msg, trash, sizeof(trash));
@@ -1874,9 +1865,9 @@
break;
}
- if (buffer_write_chunk(rep, &msg) >= 0) {
+ if (buffer_feed_chunk(rep, &msg) >= 0) {
/* Socket buffer full. Let's try again later from the same point */
- return;
+ return 0;
}
s->data_ctx.errors.ptr = 0;
s->data_ctx.errors.sid = es->sid;
@@ -1886,24 +1877,24 @@
/* the snapshot changed while we were dumping it */
chunk_printf(&msg,
" WARNING! update detected on this snapshot, dump interrupted. Please re-check!\n");
- if (buffer_write_chunk(rep, &msg) >= 0)
- return;
+ if (buffer_feed_chunk(rep, &msg) >= 0)
+ return 0;
goto next;
}
/* OK, ptr >= 0, so we have to dump the current line */
- while (s->data_ctx.errors.ptr < es->len) {
+ while (s->data_ctx.errors.ptr < es->len && s->data_ctx.errors.ptr < sizeof(es->buf)) {
int newptr;
int newline;
newline = s->data_ctx.errors.bol;
newptr = dump_error_line(&msg, es, &newline, s->data_ctx.errors.ptr);
if (newptr == s->data_ctx.errors.ptr)
- return;
+ return 0;
- if (buffer_write_chunk(rep, &msg) >= 0) {
+ if (buffer_feed_chunk(rep, &msg) >= 0) {
/* Socket buffer full. Let's try again later from the same point */
- return;
+ return 0;
}
s->data_ctx.errors.ptr = newptr;
s->data_ctx.errors.bol = newline;
@@ -1919,8 +1910,7 @@
}
/* dump complete */
- buffer_stop_hijack(rep);
- s->ana_state = STATS_ST_CLOSE;
+ return 1;
}