]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MINOR] stats_dump_errors_to_buffer: use buffer_feed_chunk()
authorWilly Tarreau <w@1wt.eu>
Sat, 3 Oct 2009 21:49:35 +0000 (23:49 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 4 Oct 2009 09:00:11 +0000 (11:00 +0200)
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.

include/proto/dumpstats.h
src/dumpstats.c

index 7a92c987da9419f37508db1a344f13ce38247f0f..4dd9e3488feeae33b87e806c722d328e2db4c02e 100644 (file)
@@ -51,7 +51,7 @@ void stats_dump_raw_to_buffer(struct session *s, struct buffer *req);
 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 */
index 8b9593306f826a6a4626fef5c28bbc13f0865bbc..6c8c97bba4df3ebdfec5b9e6ace52668d9e40604 100644 (file)
@@ -429,9 +429,7 @@ void stats_io_handler(struct stream_interface *si)
                                        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 @@ static int dump_error_line(struct chunk *out, struct error_snapshot *err,
 
        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 @@ static int dump_error_line(struct chunk *out, struct error_snapshot *err,
  * 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 @@ void stats_dump_errors_to_buffer(struct session *s, struct buffer *rep)
                                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 @@ void stats_dump_errors_to_buffer(struct session *s, struct buffer *rep)
                        /* 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 @@ void stats_dump_errors_to_buffer(struct session *s, struct buffer *rep)
        }
 
        /* dump complete */
-       buffer_stop_hijack(rep);
-       s->ana_state = STATS_ST_CLOSE;
+       return 1;
 }