blob: d5dd781bcbe85b08cd9e64bf912ea0dc02be59c5 [file] [log] [blame]
Willy Tarreaubaaee002006-06-26 02:48:02 +02001/*
Willy Tarreau7c3c5412009-12-13 15:53:05 +01002 * include/proto/buffers.h
3 * Buffer management definitions, macros and inline functions.
4 *
5 * Copyright (C) 2000-2009 Willy Tarreau - w@1wt.eu
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation, version 2.1
10 * exclusively.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
Willy Tarreaubaaee002006-06-26 02:48:02 +020021
22#ifndef _PROTO_BUFFERS_H
23#define _PROTO_BUFFERS_H
24
Willy Tarreau7341d942007-05-13 19:56:02 +020025#include <stdio.h>
Willy Tarreau0f772532006-12-23 20:51:41 +010026#include <stdlib.h>
Willy Tarreau7341d942007-05-13 19:56:02 +020027#include <string.h>
Willy Tarreau0f772532006-12-23 20:51:41 +010028
Willy Tarreaue3ba5f02006-06-29 18:54:54 +020029#include <common/config.h>
Willy Tarreau7341d942007-05-13 19:56:02 +020030#include <common/memory.h>
Willy Tarreau0c303ee2008-07-07 00:09:58 +020031#include <common/ticks.h>
Willy Tarreaufa645582007-06-03 15:59:52 +020032#include <common/time.h>
33
Willy Tarreaubaaee002006-06-26 02:48:02 +020034#include <types/buffers.h>
Willy Tarreau7c3c5412009-12-13 15:53:05 +010035#include <types/global.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020036
Willy Tarreau7341d942007-05-13 19:56:02 +020037extern struct pool_head *pool2_buffer;
38
39/* perform minimal intializations, report 0 in case of error, 1 if OK. */
40int init_buffer();
41
Willy Tarreau7c3c5412009-12-13 15:53:05 +010042/* Initialize all fields in the buffer. The BF_OUT_EMPTY flags is set. */
Willy Tarreau54469402006-07-29 16:59:06 +020043static inline void buffer_init(struct buffer *buf)
44{
Willy Tarreauf890dc92008-12-13 21:12:26 +010045 buf->send_max = 0;
Willy Tarreau6b66f3e2008-12-14 17:31:54 +010046 buf->to_forward = 0;
Willy Tarreaue393fe22008-08-16 22:18:07 +020047 buf->l = buf->total = 0;
Willy Tarreau3eba98a2009-01-25 13:56:13 +010048 buf->pipe = NULL;
Willy Tarreau2df28e82008-08-17 15:20:19 +020049 buf->analysers = 0;
Willy Tarreaufa7e1022008-10-19 07:30:41 +020050 buf->cons = NULL;
Willy Tarreauba0b63d2009-09-20 08:09:44 +020051 buf->flags = BF_OUT_EMPTY;
Willy Tarreau2df28e82008-08-17 15:20:19 +020052 buf->r = buf->lr = buf->w = buf->data;
Willy Tarreau54469402006-07-29 16:59:06 +020053}
54
Willy Tarreau7c3c5412009-12-13 15:53:05 +010055/* Return the max number of bytes the buffer can contain so that once all the
56 * pending bytes are forwarded, the buffer still has global.tune.maxrewrite
57 * bytes free. The result sits between buf->size - maxrewrite and buf->size.
58 */
59static inline int buffer_max_len(struct buffer *buf)
60{
61 if (buf->to_forward == BUF_INFINITE_FORWARD ||
62 buf->to_forward + buf->send_max >= global.tune.maxrewrite)
63 return buf->size;
64 else
65 return buf->size - global.tune.maxrewrite + buf->to_forward + buf->send_max;
66}
67
Willy Tarreau2eb52f02008-09-04 09:14:08 +020068/* Check buffer timeouts, and set the corresponding flags. The
69 * likely/unlikely have been optimized for fastest normal path.
Willy Tarreaudd80c6f2008-12-13 22:25:59 +010070 * The read/write timeouts are not set if there was activity on the buffer.
71 * That way, we don't have to update the timeout on every I/O. Note that the
72 * analyser timeout is always checked.
Willy Tarreau2eb52f02008-09-04 09:14:08 +020073 */
74static inline void buffer_check_timeouts(struct buffer *b)
75{
Willy Tarreau86491c32008-12-14 09:04:47 +010076 if (likely(!(b->flags & (BF_SHUTR|BF_READ_TIMEOUT|BF_READ_ACTIVITY|BF_READ_NOEXP))) &&
Willy Tarreau2eb52f02008-09-04 09:14:08 +020077 unlikely(tick_is_expired(b->rex, now_ms)))
78 b->flags |= BF_READ_TIMEOUT;
79
Willy Tarreaudd80c6f2008-12-13 22:25:59 +010080 if (likely(!(b->flags & (BF_SHUTW|BF_WRITE_TIMEOUT|BF_WRITE_ACTIVITY))) &&
Willy Tarreau2eb52f02008-09-04 09:14:08 +020081 unlikely(tick_is_expired(b->wex, now_ms)))
82 b->flags |= BF_WRITE_TIMEOUT;
83
84 if (likely(!(b->flags & BF_ANA_TIMEOUT)) &&
85 unlikely(tick_is_expired(b->analyse_exp, now_ms)))
86 b->flags |= BF_ANA_TIMEOUT;
87}
88
Willy Tarreau0abebcc2009-01-08 00:09:41 +010089/* Schedule <bytes> more bytes to be forwarded by the buffer without notifying
90 * the task. Any pending data in the buffer is scheduled to be sent as well,
91 * in the limit of the number of bytes to forward. This must be the only method
92 * to use to schedule bytes to be sent. Directly touching ->to_forward will
93 * cause lockups when send_max goes down to zero if nobody is ready to push the
94 * remaining data.
95 */
Willy Tarreau31971e52009-09-20 12:07:52 +020096static inline void buffer_forward(struct buffer *buf, unsigned long bytes)
Willy Tarreau0abebcc2009-01-08 00:09:41 +010097{
Willy Tarreau31971e52009-09-20 12:07:52 +020098 unsigned long data_left;
Willy Tarreau0abebcc2009-01-08 00:09:41 +010099
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200100 if (!bytes)
101 return;
Willy Tarreau0abebcc2009-01-08 00:09:41 +0100102 data_left = buf->l - buf->send_max;
Willy Tarreau91aa5772009-09-15 20:32:30 +0200103 if (data_left >= bytes) {
104 buf->send_max += bytes;
Willy Tarreau2d028db2009-09-20 22:56:25 +0200105 buf->flags &= ~BF_OUT_EMPTY;
Willy Tarreau91aa5772009-09-15 20:32:30 +0200106 return;
107 }
Willy Tarreau0abebcc2009-01-08 00:09:41 +0100108
Willy Tarreau0abebcc2009-01-08 00:09:41 +0100109 buf->send_max += data_left;
Willy Tarreau2d028db2009-09-20 22:56:25 +0200110 if (buf->send_max)
111 buf->flags &= ~BF_OUT_EMPTY;
112
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100113 if (buf->to_forward != BUF_INFINITE_FORWARD) {
114 buf->to_forward += bytes - data_left;
115 if (bytes == BUF_INFINITE_FORWARD)
116 buf->to_forward = bytes;
117 }
Willy Tarreau31971e52009-09-20 12:07:52 +0200118
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100119 if (buf->l < buffer_max_len(buf))
120 buf->flags &= ~BF_FULL;
121 else
122 buf->flags |= BF_FULL;
Willy Tarreau0abebcc2009-01-08 00:09:41 +0100123}
124
Willy Tarreaue8a28bf2009-03-08 21:12:04 +0100125/* Schedule all remaining buffer data to be sent. send_max is not touched if it
126 * already covers those data. That permits doing a flush even after a forward,
127 * although not recommended.
128 */
129static inline void buffer_flush(struct buffer *buf)
130{
131 if (buf->send_max < buf->l)
132 buf->send_max = buf->l;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200133 if (buf->send_max)
134 buf->flags &= ~BF_OUT_EMPTY;
Willy Tarreaue8a28bf2009-03-08 21:12:04 +0100135}
136
Willy Tarreau6f0aa472009-03-08 20:33:29 +0100137/* Erase any content from buffer <buf> and adjusts flags accordingly. Note
Willy Tarreau0abebcc2009-01-08 00:09:41 +0100138 * that any spliced data is not affected since we may not have any access to
139 * it.
Willy Tarreaue393fe22008-08-16 22:18:07 +0200140 */
Willy Tarreau6f0aa472009-03-08 20:33:29 +0100141static inline void buffer_erase(struct buffer *buf)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200142{
Willy Tarreauf890dc92008-12-13 21:12:26 +0100143 buf->send_max = 0;
Willy Tarreau6b66f3e2008-12-14 17:31:54 +0100144 buf->to_forward = 0;
Willy Tarreaue09e0ce2007-03-18 16:31:29 +0100145 buf->r = buf->lr = buf->w = buf->data;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200146 buf->l = 0;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200147 buf->flags &= ~(BF_FULL | BF_OUT_EMPTY);
148 if (!buf->pipe)
149 buf->flags |= BF_OUT_EMPTY;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200150}
151
Willy Tarreau9cb8daa2009-09-15 21:22:24 +0200152/* Cut the "tail" of the buffer, which means strip it to the length of unsent
153 * data only, and kill any remaining unsent data. Any scheduled forwarding is
154 * stopped. This is mainly to be used to send error messages after existing
155 * data.
156 */
157static inline void buffer_cut_tail(struct buffer *buf)
158{
159 if (!buf->send_max)
160 return buffer_erase(buf);
161
162 buf->to_forward = 0;
163 if (buf->l == buf->send_max)
164 return;
165
166 buf->l = buf->send_max;
167 buf->r = buf->w + buf->l;
168 if (buf->r >= buf->data + buf->size)
169 buf->r -= buf->size;
170 buf->lr = buf->r;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200171 buf->flags &= ~BF_FULL;
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100172 if (buf->l >= buffer_max_len(buf))
Willy Tarreau9cb8daa2009-09-15 21:22:24 +0200173 buf->flags |= BF_FULL;
174}
175
Willy Tarreaud21e01c2009-12-27 15:45:38 +0100176/* Cut the <n> next unsent bytes of the buffer. The caller must ensure that <n>
177 * is smaller than the actual buffer's length. This is mainly used to remove
178 * empty lines at the beginning of a request or a response.
179 */
180static inline void buffer_ignore(struct buffer *buf, int n)
181{
182 buf->l -= n;
183 buf->w += n;
184 if (buf->w >= buf->data + buf->size)
185 buf->w -= buf->size;
186 buf->flags &= ~BF_FULL;
187 if (buf->l >= buffer_max_len(buf))
188 buf->flags |= BF_FULL;
189}
190
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200191/* marks the buffer as "shutdown" ASAP for reads */
192static inline void buffer_shutr_now(struct buffer *buf)
193{
Willy Tarreaufe3718a2008-11-30 18:14:12 +0100194 buf->flags |= BF_SHUTR_NOW;
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200195}
196
197/* marks the buffer as "shutdown" ASAP for writes */
198static inline void buffer_shutw_now(struct buffer *buf)
199{
200 buf->flags |= BF_SHUTW_NOW;
201}
202
203/* marks the buffer as "shutdown" ASAP in both directions */
204static inline void buffer_abort(struct buffer *buf)
205{
Willy Tarreaufe3718a2008-11-30 18:14:12 +0100206 buf->flags |= BF_SHUTR_NOW | BF_SHUTW_NOW;
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200207}
208
Willy Tarreau01bf8672008-12-07 18:03:29 +0100209/* Installs <func> as a hijacker on the buffer <b> for session <s>. The hijack
210 * flag is set, and the function called once. The function is responsible for
211 * clearing the hijack bit. It is possible that the function clears the flag
212 * during this first call.
213 */
214static inline void buffer_install_hijacker(struct session *s,
215 struct buffer *b,
216 void (*func)(struct session *, struct buffer *))
Willy Tarreau72b179a2008-08-28 16:01:32 +0200217{
Willy Tarreau01bf8672008-12-07 18:03:29 +0100218 b->hijacker = func;
219 b->flags |= BF_HIJACK;
220 func(s, b);
Willy Tarreau72b179a2008-08-28 16:01:32 +0200221}
222
Willy Tarreau01bf8672008-12-07 18:03:29 +0100223/* Releases the buffer from hijacking mode. Often used by the hijack function */
Willy Tarreau72b179a2008-08-28 16:01:32 +0200224static inline void buffer_stop_hijack(struct buffer *buf)
225{
226 buf->flags &= ~BF_HIJACK;
227}
228
Willy Tarreau520d95e2009-09-19 21:04:57 +0200229/* allow the consumer to try to establish a new connection. */
230static inline void buffer_auto_connect(struct buffer *buf)
Willy Tarreau3da77c52008-08-29 09:58:42 +0200231{
Willy Tarreau520d95e2009-09-19 21:04:57 +0200232 buf->flags |= BF_AUTO_CONNECT;
Willy Tarreau3da77c52008-08-29 09:58:42 +0200233}
234
Willy Tarreau520d95e2009-09-19 21:04:57 +0200235/* prevent the consumer from trying to establish a new connection, and also
236 * disable auto shutdown forwarding.
237 */
238static inline void buffer_dont_connect(struct buffer *buf)
Willy Tarreau3da77c52008-08-29 09:58:42 +0200239{
Willy Tarreau520d95e2009-09-19 21:04:57 +0200240 buf->flags &= ~(BF_AUTO_CONNECT|BF_AUTO_CLOSE);
Willy Tarreau3da77c52008-08-29 09:58:42 +0200241}
242
Willy Tarreau520d95e2009-09-19 21:04:57 +0200243/* allow the producer to forward shutdown requests */
244static inline void buffer_auto_close(struct buffer *buf)
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100245{
Willy Tarreau520d95e2009-09-19 21:04:57 +0200246 buf->flags |= BF_AUTO_CLOSE;
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100247}
248
Willy Tarreau520d95e2009-09-19 21:04:57 +0200249/* prevent the producer from forwarding shutdown requests */
250static inline void buffer_dont_close(struct buffer *buf)
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100251{
Willy Tarreau520d95e2009-09-19 21:04:57 +0200252 buf->flags &= ~BF_AUTO_CLOSE;
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100253}
254
Willy Tarreaubaaee002006-06-26 02:48:02 +0200255/* returns the maximum number of bytes writable at once in this buffer */
Willy Tarreaub17916e2006-10-15 15:17:57 +0200256static inline int buffer_max(const struct buffer *buf)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200257{
Willy Tarreaua07a34e2009-08-16 23:27:46 +0200258 if (buf->l == buf->size)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200259 return 0;
260 else if (buf->r >= buf->w)
Willy Tarreaua07a34e2009-08-16 23:27:46 +0200261 return buf->data + buf->size - buf->r;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200262 else
263 return buf->w - buf->r;
264}
265
Willy Tarreaubaaee002006-06-26 02:48:02 +0200266/*
267 * Tries to realign the given buffer, and returns how many bytes can be written
268 * there at once without overwriting anything.
269 */
270static inline int buffer_realign(struct buffer *buf)
271{
272 if (buf->l == 0) {
273 /* let's realign the buffer to optimize I/O */
Willy Tarreaue09e0ce2007-03-18 16:31:29 +0100274 buf->r = buf->w = buf->lr = buf->data;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200275 }
276 return buffer_max(buf);
277}
278
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200279/*
280 * Return the max amount of bytes that can be stuffed into the buffer at once.
281 * Note that this may be lower than the actual buffer size when the free space
282 * wraps after the end, so it's preferable to call this function again after
283 * writing. Also note that this function respects max_len.
284 */
285static inline int buffer_contig_space(struct buffer *buf)
286{
287 int ret;
288
289 if (buf->l == 0) {
290 buf->r = buf->w = buf->lr = buf->data;
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100291 ret = buffer_max_len(buf);
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200292 }
293 else if (buf->r > buf->w) {
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100294 ret = buf->data + buffer_max_len(buf) - buf->r;
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200295 }
296 else {
297 ret = buf->w - buf->r;
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100298 if (ret > buffer_max_len(buf))
299 ret = buffer_max_len(buf);
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200300 }
301 return ret;
302}
303
Willy Tarreau4e33d862009-10-11 23:35:10 +0200304/* Return 1 if the buffer has less than 1/4 of its capacity free, otherwise 0 */
305static inline int buffer_almost_full(struct buffer *buf)
306{
307 if (buffer_contig_space(buf) < buf->size / 4)
308 return 1;
309 return 0;
310}
311
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200312/*
313 * Return the max amount of bytes that can be read from the buffer at once.
314 * Note that this may be lower than the actual buffer length when the data
315 * wrap after the end, so it's preferable to call this function again after
316 * reading. Also note that this function respects the send_max limit.
317 */
318static inline int buffer_contig_data(struct buffer *buf)
319{
320 int ret;
321
322 if (!buf->send_max || !buf->l)
323 return 0;
324
325 if (buf->r > buf->w)
326 ret = buf->r - buf->w;
327 else
328 ret = buf->data + buf->size - buf->w;
329
330 /* limit the amount of outgoing data if required */
331 if (ret > buf->send_max)
332 ret = buf->send_max;
333
334 return ret;
335}
336
337/*
338 * Advance the buffer's read pointer by <len> bytes. This is useful when data
339 * have been read directly from the buffer. It is illegal to call this function
340 * with <len> causing a wrapping at the end of the buffer. It's the caller's
Willy Tarreau2e1dd3d2009-09-23 22:56:07 +0200341 * responsibility to ensure that <len> is never larger than buf->send_max.
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200342 */
343static inline void buffer_skip(struct buffer *buf, int len)
344{
345 buf->w += len;
Willy Tarreau2e1dd3d2009-09-23 22:56:07 +0200346 if (buf->w >= buf->data + buf->size)
347 buf->w -= buf->size; /* wrap around the buffer */
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200348
349 buf->l -= len;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200350 if (!buf->l)
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200351 buf->r = buf->w = buf->lr = buf->data;
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200352
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100353 if (buf->l < buffer_max_len(buf))
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200354 buf->flags &= ~BF_FULL;
355
356 buf->send_max -= len;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200357 if (!buf->send_max && !buf->pipe)
358 buf->flags |= BF_OUT_EMPTY;
Willy Tarreaufb0e9202009-09-23 23:47:55 +0200359
360 /* notify that some data was written to the SI from the buffer */
361 buf->flags |= BF_WRITE_PARTIAL;
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200362}
Willy Tarreaubaaee002006-06-26 02:48:02 +0200363
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200364/*
365 * Return one char from the buffer. If the buffer is empty and closed, return -1.
366 * If the buffer is just empty, return -2. The buffer's pointer is not advanced,
367 * it's up to the caller to call buffer_skip(buf, 1) when it has consumed the char.
368 * Also note that this function respects the send_max limit.
369 */
370static inline int buffer_si_peekchar(struct buffer *buf)
371{
372 if (buf->send_max)
373 return *buf->w;
374
375 if (buf->flags & (BF_SHUTW|BF_SHUTW_NOW))
376 return -1;
377 else
378 return -2;
379}
380
Willy Tarreauc77e7612009-09-13 14:58:00 +0200381/* Try to write character <c> into buffer <buf> after length controls. This
Willy Tarreau9bcc91e2009-10-10 18:01:44 +0200382 * work like buffer_feed2(buf, &c, 1).
Willy Tarreauc77e7612009-09-13 14:58:00 +0200383 * Returns non-zero in case of success, 0 if the buffer was full.
384 * The send limit is automatically adjusted with the amount of data written.
385 */
386static inline int buffer_si_putchar(struct buffer *buf, char c)
387{
388 if (buf->flags & BF_FULL)
389 return 0;
390
Willy Tarreauc77e7612009-09-13 14:58:00 +0200391 *buf->r = c;
392
393 buf->l++;
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100394 if (buf->l >= buffer_max_len(buf))
Willy Tarreauc77e7612009-09-13 14:58:00 +0200395 buf->flags |= BF_FULL;
396
397 buf->r++;
398 if (buf->r - buf->data == buf->size)
399 buf->r -= buf->size;
400
Willy Tarreau31971e52009-09-20 12:07:52 +0200401 if (buf->to_forward >= 1) {
402 if (buf->to_forward != BUF_INFINITE_FORWARD)
403 buf->to_forward--;
Willy Tarreauc77e7612009-09-13 14:58:00 +0200404 buf->send_max++;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200405 buf->flags &= ~BF_OUT_EMPTY;
Willy Tarreauc77e7612009-09-13 14:58:00 +0200406 }
407
408 buf->total++;
409 return 1;
410}
411
Willy Tarreaubaaee002006-06-26 02:48:02 +0200412int buffer_write(struct buffer *buf, const char *msg, int len);
Willy Tarreau9bcc91e2009-10-10 18:01:44 +0200413int buffer_feed2(struct buffer *buf, const char *str, int len);
Willy Tarreau36a5c532009-09-03 07:13:50 +0200414int buffer_si_putchar(struct buffer *buf, char c);
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200415int buffer_si_peekline(struct buffer *buf, char *str, int len);
Willy Tarreau4af6f3a2007-03-18 22:36:26 +0100416int buffer_replace(struct buffer *b, char *pos, char *end, const char *str);
417int buffer_replace2(struct buffer *b, char *pos, char *end, const char *str, int len);
418int buffer_insert_line2(struct buffer *b, char *pos, const char *str, int len);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +0100419void buffer_dump(FILE *o, struct buffer *b, int from, int to);
Willy Tarreaubaaee002006-06-26 02:48:02 +0200420
Willy Tarreauaeac3192009-08-31 08:09:57 +0200421
422/* writes the chunk <chunk> to buffer <buf>. Returns -1 in case of success,
423 * -2 if it is larger than the buffer size, or the number of bytes available
424 * otherwise. If the chunk has been written, its size is automatically reset
425 * to zero. The send limit is automatically adjusted with the amount of data
426 * written.
427 */
428static inline int buffer_write_chunk(struct buffer *buf, struct chunk *chunk)
429{
430 int ret;
431
432 ret = buffer_write(buf, chunk->str, chunk->len);
433 if (ret == -1)
434 chunk->len = 0;
435 return ret;
436}
437
438/* Try to write chunk <chunk> into buffer <buf> after length controls. This is
439 * the equivalent of buffer_write_chunk() except that to_forward and send_max
440 * are updated and that max_len is respected. Returns -1 in case of success,
441 * -2 if it is larger than the buffer size, or the number of bytes available
442 * otherwise. If the chunk has been written, its size is automatically reset
443 * to zero. The send limit is automatically adjusted with the amount of data
444 * written.
445 */
446static inline int buffer_feed_chunk(struct buffer *buf, struct chunk *chunk)
447{
448 int ret;
449
Willy Tarreau9bcc91e2009-10-10 18:01:44 +0200450 ret = buffer_feed2(buf, chunk->str, chunk->len);
Willy Tarreauaeac3192009-08-31 08:09:57 +0200451 if (ret == -1)
452 chunk->len = 0;
453 return ret;
454}
455
Willy Tarreau9bcc91e2009-10-10 18:01:44 +0200456/* Try to write string <str> into buffer <buf> after length controls. This is
457 * the equivalent of buffer_feed2() except that string length is measured by
458 * the function. Returns -1 in case of success, -2 if it is larger than the
459 * buffer size, or the number of bytes available otherwise. The send limit is
460 * automatically adjusted with the amount of data written.
461 */
462static inline int buffer_feed(struct buffer *buf, const char *str)
463{
464 return buffer_feed2(buf, str, strlen(str));
465}
466
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +0200467static inline void chunk_init(struct chunk *chk, char *str, size_t size) {
468 chk->str = str;
469 chk->len = 0;
470 chk->size = size;
471}
472
473/* report 0 in case of error, 1 if OK. */
Krzysztof Piotr Oledzki6f61b212009-10-04 23:34:15 +0200474static inline int chunk_initlen(struct chunk *chk, char *str, size_t size, int len) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +0200475
Krzysztof Piotr Oledzki6f61b212009-10-04 23:34:15 +0200476 if (size && len > size)
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +0200477 return 0;
478
479 chk->str = str;
480 chk->len = len;
481 chk->size = size;
482
483 return 1;
484}
485
486static inline void chunk_initstr(struct chunk *chk, char *str) {
487 chk->str = str;
488 chk->len = strlen(str);
489 chk->size = 0; /* mark it read-only */
490}
491
492static inline int chunk_strcpy(struct chunk *chk, const char *str) {
493 size_t len;
494
495 len = strlen(str);
496
497 if (unlikely(len > chk->size))
498 return 0;
499
500 chk->len = len;
501 memcpy(chk->str, str, len);
502
503 return 1;
504}
505
506int chunk_printf(struct chunk *chk, const char *fmt, ...)
507 __attribute__ ((format(printf, 2, 3)));
508
Krzysztof Piotr Oledzkiba8d7d32009-10-10 21:06:03 +0200509int chunk_htmlencode(struct chunk *dst, struct chunk *src);
510int chunk_asciiencode(struct chunk *dst, struct chunk *src, char qc);
511
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +0200512static inline void chunk_reset(struct chunk *chk) {
513 chk->str = NULL;
514 chk->len = -1;
515 chk->size = 0;
516}
517
518static inline void chunk_destroy(struct chunk *chk) {
519
520 if (!chk->size)
521 return;
522
523 if (chk->str)
524 free(chk->str);
525
526 chunk_reset(chk);
527}
528
Willy Tarreau0f772532006-12-23 20:51:41 +0100529/*
530 * frees the destination chunk if already allocated, allocates a new string,
531 * and copies the source into it. The pointer to the destination string is
532 * returned, or NULL if the allocation fails or if any pointer is NULL..
533 */
534static inline char *chunk_dup(struct chunk *dst, const struct chunk *src) {
535 if (!dst || !src || !src->str)
536 return NULL;
537 if (dst->str)
538 free(dst->str);
539 dst->len = src->len;
540 dst->str = (char *)malloc(dst->len);
541 memcpy(dst->str, src->str, dst->len);
542 return dst->str;
543}
Willy Tarreaubaaee002006-06-26 02:48:02 +0200544
545#endif /* _PROTO_BUFFERS_H */
546
547/*
548 * Local variables:
549 * c-indent-level: 8
550 * c-basic-offset: 8
551 * End:
552 */