]> git.kaiwu.me - haproxy.git/commitdiff
[BUG] Flush buffers also where there are exactly 0 bytes left
authorKrzysztof Piotr Oledzki <ole@ans.pl>
Sun, 20 Apr 2008 19:34:47 +0000 (21:34 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 21 Apr 2008 05:24:39 +0000 (07:24 +0200)
I noticed it was possible to get truncated http/csv stats. Sometimes.
Usually the problem disappeared as fast as it appeared, but once it
happend that my http-stats page was truncated for about one hour.
It was quite weird as it happened independently for csv and http
output and it took me some time to track & fix this bug.

Both buffer_write & buffer_write_chunk used to return 0 in two
situations: is case of success or where there was exactly 0 bytes
left. The first one is intentional but I believe the second one
is not as it was not possible to distinguish between successful
write and unsuccessful one, which means that if the buffer was 100%
filled, it was never flushed and it was not possible to write
more data.

This patch fixes this problem.

src/buffers.c
src/dumpstats.c

index 8b2c4d33eb34ac9f6094563eca08a6264443022c..fa6b8a906ad7c5811efcd23b106d7d9fb76c2f6f 100644 (file)
@@ -29,7 +29,7 @@ int init_buffer()
 }
 
 
-/* writes <len> bytes from message <msg> to buffer <buf>. Returns 0 in case of
+/* writes <len> bytes from message <msg> to buffer <buf>. Returns -1 in case of
  * success, or the number of bytes available otherwise.
  * FIXME-20060521: handle unaligned data.
  */
@@ -48,10 +48,11 @@ int buffer_write(struct buffer *buf, const char *msg, int len)
        buf->total += len;
        if (buf->r == buf->data + BUFSIZE)
                buf->r = buf->data;
-       return 0;
+
+       return -1;
 }
 
-/* writes the chunk <chunk> to buffer <buf>. Returns 0 in case of
+/* writes the chunk <chunk> to buffer <buf>. Returns -1 in case of
  * success, or the number of bytes available otherwise. If the chunk
  * has been written, its size is automatically reset to zero.
  */
@@ -60,7 +61,7 @@ int buffer_write_chunk(struct buffer *buf, struct chunk *chunk)
        int max;
 
        if (chunk->len == 0)
-               return 0;
+               return -1;
 
        max = buffer_realign(buf);
 
@@ -74,7 +75,8 @@ int buffer_write_chunk(struct buffer *buf, struct chunk *chunk)
        if (buf->r == buf->data + BUFSIZE)
                buf->r = buf->data;
        chunk->len = 0;
-       return 0;
+
+       return -1;
 }
 
 /*
index 8f5f17ea184084976033690fc0adbbb9c5832c6f..91d46544d81b801e7ec90b2b93b6c78050254706 100644 (file)
@@ -204,7 +204,7 @@ int stats_dump_raw(struct session *s, struct uri_auth *uri)
        case DATA_ST_HEAD:
                if (s->data_ctx.stats.flags & STAT_SHOW_STAT) {
                        print_csv_header(&msg, sizeof(trash));
-                       if (buffer_write_chunk(rep, &msg) != 0)
+                       if (buffer_write_chunk(rep, &msg) >= 0)
                                return 0;
                }
 
@@ -240,7 +240,7 @@ int stats_dump_raw(struct session *s, struct uri_auth *uri)
                                     global.maxconn,
                                     actconn
                                     );
-                       if (buffer_write_chunk(rep, &msg) != 0)
+                       if (buffer_write_chunk(rep, &msg) >= 0)
                                return 0;
                }
 
@@ -418,7 +418,7 @@ int stats_dump_http(struct session *s, struct uri_auth *uri)
                } else {
                        print_csv_header(&msg, sizeof(trash));
                }
-               if (buffer_write_chunk(rep, &msg) != 0)
+               if (buffer_write_chunk(rep, &msg) >= 0)
                        return 0;
 
                s->data_state = DATA_ST_INFO;
@@ -528,7 +528,7 @@ int stats_dump_http(struct session *s, struct uri_auth *uri)
                             ""
                             );
            
-                       if (buffer_write_chunk(rep, &msg) != 0)
+                       if (buffer_write_chunk(rep, &msg) >= 0)
                                return 0;
                }
 
@@ -557,7 +557,7 @@ int stats_dump_http(struct session *s, struct uri_auth *uri)
        case DATA_ST_END:
                if (!(s->data_ctx.stats.flags & STAT_FMT_CSV)) {
                        chunk_printf(&msg, sizeof(trash), "</body></html>\n");
-                       if (buffer_write_chunk(rep, &msg) != 0)
+                       if (buffer_write_chunk(rep, &msg) >= 0)
                                return 0;
                }
 
@@ -648,7 +648,7 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
                                     "</tr>",
                                     px->id);
 
-                       if (buffer_write_chunk(rep, &msg) != 0)
+                       if (buffer_write_chunk(rep, &msg) >= 0)
                                return 0;
                }
 
@@ -716,7 +716,7 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
                                     relative_pid, px->uuid);
                        }
 
-                       if (buffer_write_chunk(rep, &msg) != 0)
+                       if (buffer_write_chunk(rep, &msg) >= 0)
                                return 0;
                }
 
@@ -908,7 +908,7 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
                                /* ',' then EOL */
                                chunk_printf(&msg, sizeof(trash), ",\n");
                        }
-                       if (buffer_write_chunk(rep, &msg) != 0)
+                       if (buffer_write_chunk(rep, &msg) >= 0)
                                return 0;
 
                        s->data_ctx.stats.sv = sv->next;
@@ -1006,7 +1006,7 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
                                     relative_pid, px->uuid,
                                     px->cum_lbconn);
                        }
-                       if (buffer_write_chunk(rep, &msg) != 0)
+                       if (buffer_write_chunk(rep, &msg) >= 0)
                                return 0;
                }
                
@@ -1017,7 +1017,7 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
                if (!(s->data_ctx.stats.flags & STAT_FMT_CSV)) {
                        chunk_printf(&msg, sizeof(trash), "</table><p>\n");
 
-                       if (buffer_write_chunk(rep, &msg) != 0)
+                       if (buffer_write_chunk(rep, &msg) >= 0)
                                return 0;
                }