blob: 870dadb614dfa6dfcc401ac5e3890673d6db07e1 [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 *
Willy Tarreaub97f1992010-02-25 23:54:31 +01005 * Copyright (C) 2000-2010 Willy Tarreau - w@1wt.eu
Willy Tarreau7c3c5412009-12-13 15:53:05 +01006 *
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 Tarreaue4599762010-03-21 23:25:09 +0100207 buf->flags &= ~BF_AUTO_CONNECT;
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200208}
209
Willy Tarreau01bf8672008-12-07 18:03:29 +0100210/* Installs <func> as a hijacker on the buffer <b> for session <s>. The hijack
211 * flag is set, and the function called once. The function is responsible for
212 * clearing the hijack bit. It is possible that the function clears the flag
213 * during this first call.
214 */
215static inline void buffer_install_hijacker(struct session *s,
216 struct buffer *b,
217 void (*func)(struct session *, struct buffer *))
Willy Tarreau72b179a2008-08-28 16:01:32 +0200218{
Willy Tarreau01bf8672008-12-07 18:03:29 +0100219 b->hijacker = func;
220 b->flags |= BF_HIJACK;
221 func(s, b);
Willy Tarreau72b179a2008-08-28 16:01:32 +0200222}
223
Willy Tarreau01bf8672008-12-07 18:03:29 +0100224/* Releases the buffer from hijacking mode. Often used by the hijack function */
Willy Tarreau72b179a2008-08-28 16:01:32 +0200225static inline void buffer_stop_hijack(struct buffer *buf)
226{
227 buf->flags &= ~BF_HIJACK;
228}
229
Willy Tarreau520d95e2009-09-19 21:04:57 +0200230/* allow the consumer to try to establish a new connection. */
231static inline void buffer_auto_connect(struct buffer *buf)
Willy Tarreau3da77c52008-08-29 09:58:42 +0200232{
Willy Tarreau520d95e2009-09-19 21:04:57 +0200233 buf->flags |= BF_AUTO_CONNECT;
Willy Tarreau3da77c52008-08-29 09:58:42 +0200234}
235
Willy Tarreau520d95e2009-09-19 21:04:57 +0200236/* prevent the consumer from trying to establish a new connection, and also
237 * disable auto shutdown forwarding.
238 */
239static inline void buffer_dont_connect(struct buffer *buf)
Willy Tarreau3da77c52008-08-29 09:58:42 +0200240{
Willy Tarreau520d95e2009-09-19 21:04:57 +0200241 buf->flags &= ~(BF_AUTO_CONNECT|BF_AUTO_CLOSE);
Willy Tarreau3da77c52008-08-29 09:58:42 +0200242}
243
Willy Tarreau520d95e2009-09-19 21:04:57 +0200244/* allow the producer to forward shutdown requests */
245static inline void buffer_auto_close(struct buffer *buf)
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100246{
Willy Tarreau520d95e2009-09-19 21:04:57 +0200247 buf->flags |= BF_AUTO_CLOSE;
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100248}
249
Willy Tarreau520d95e2009-09-19 21:04:57 +0200250/* prevent the producer from forwarding shutdown requests */
251static inline void buffer_dont_close(struct buffer *buf)
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100252{
Willy Tarreau520d95e2009-09-19 21:04:57 +0200253 buf->flags &= ~BF_AUTO_CLOSE;
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100254}
255
Willy Tarreau90deb182010-01-07 00:20:41 +0100256/* allow the producer to read / poll the input */
257static inline void buffer_auto_read(struct buffer *buf)
258{
259 buf->flags &= ~BF_DONT_READ;
260}
261
262/* prevent the producer from read / poll the input */
263static inline void buffer_dont_read(struct buffer *buf)
264{
265 buf->flags |= BF_DONT_READ;
266}
267
Willy Tarreaubaaee002006-06-26 02:48:02 +0200268/* returns the maximum number of bytes writable at once in this buffer */
Willy Tarreaub17916e2006-10-15 15:17:57 +0200269static inline int buffer_max(const struct buffer *buf)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200270{
Willy Tarreaua07a34e2009-08-16 23:27:46 +0200271 if (buf->l == buf->size)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200272 return 0;
273 else if (buf->r >= buf->w)
Willy Tarreaua07a34e2009-08-16 23:27:46 +0200274 return buf->data + buf->size - buf->r;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200275 else
276 return buf->w - buf->r;
277}
278
Willy Tarreaubaaee002006-06-26 02:48:02 +0200279/*
280 * Tries to realign the given buffer, and returns how many bytes can be written
281 * there at once without overwriting anything.
282 */
283static inline int buffer_realign(struct buffer *buf)
284{
285 if (buf->l == 0) {
286 /* let's realign the buffer to optimize I/O */
Willy Tarreaue09e0ce2007-03-18 16:31:29 +0100287 buf->r = buf->w = buf->lr = buf->data;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200288 }
289 return buffer_max(buf);
290}
291
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200292/*
293 * Return the max amount of bytes that can be stuffed into the buffer at once.
294 * Note that this may be lower than the actual buffer size when the free space
295 * wraps after the end, so it's preferable to call this function again after
296 * writing. Also note that this function respects max_len.
297 */
298static inline int buffer_contig_space(struct buffer *buf)
299{
300 int ret;
301
302 if (buf->l == 0) {
303 buf->r = buf->w = buf->lr = buf->data;
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100304 ret = buffer_max_len(buf);
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200305 }
306 else if (buf->r > buf->w) {
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100307 ret = buf->data + buffer_max_len(buf) - buf->r;
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200308 }
309 else {
310 ret = buf->w - buf->r;
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100311 if (ret > buffer_max_len(buf))
312 ret = buffer_max_len(buf);
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200313 }
314 return ret;
315}
316
Willy Tarreau4e33d862009-10-11 23:35:10 +0200317/* Return 1 if the buffer has less than 1/4 of its capacity free, otherwise 0 */
318static inline int buffer_almost_full(struct buffer *buf)
319{
320 if (buffer_contig_space(buf) < buf->size / 4)
321 return 1;
322 return 0;
323}
324
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200325/*
326 * Return the max amount of bytes that can be read from the buffer at once.
327 * Note that this may be lower than the actual buffer length when the data
328 * wrap after the end, so it's preferable to call this function again after
329 * reading. Also note that this function respects the send_max limit.
330 */
331static inline int buffer_contig_data(struct buffer *buf)
332{
333 int ret;
334
335 if (!buf->send_max || !buf->l)
336 return 0;
337
338 if (buf->r > buf->w)
339 ret = buf->r - buf->w;
340 else
341 ret = buf->data + buf->size - buf->w;
342
343 /* limit the amount of outgoing data if required */
344 if (ret > buf->send_max)
345 ret = buf->send_max;
346
347 return ret;
348}
349
350/*
351 * Advance the buffer's read pointer by <len> bytes. This is useful when data
352 * have been read directly from the buffer. It is illegal to call this function
353 * with <len> causing a wrapping at the end of the buffer. It's the caller's
Willy Tarreau2e1dd3d2009-09-23 22:56:07 +0200354 * responsibility to ensure that <len> is never larger than buf->send_max.
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200355 */
356static inline void buffer_skip(struct buffer *buf, int len)
357{
358 buf->w += len;
Willy Tarreau2e1dd3d2009-09-23 22:56:07 +0200359 if (buf->w >= buf->data + buf->size)
360 buf->w -= buf->size; /* wrap around the buffer */
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200361
362 buf->l -= len;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200363 if (!buf->l)
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200364 buf->r = buf->w = buf->lr = buf->data;
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200365
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100366 if (buf->l < buffer_max_len(buf))
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200367 buf->flags &= ~BF_FULL;
368
369 buf->send_max -= len;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200370 if (!buf->send_max && !buf->pipe)
371 buf->flags |= BF_OUT_EMPTY;
Willy Tarreaufb0e9202009-09-23 23:47:55 +0200372
373 /* notify that some data was written to the SI from the buffer */
374 buf->flags |= BF_WRITE_PARTIAL;
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200375}
Willy Tarreaubaaee002006-06-26 02:48:02 +0200376
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200377/*
378 * Return one char from the buffer. If the buffer is empty and closed, return -1.
379 * If the buffer is just empty, return -2. The buffer's pointer is not advanced,
380 * it's up to the caller to call buffer_skip(buf, 1) when it has consumed the char.
381 * Also note that this function respects the send_max limit.
382 */
383static inline int buffer_si_peekchar(struct buffer *buf)
384{
385 if (buf->send_max)
386 return *buf->w;
387
388 if (buf->flags & (BF_SHUTW|BF_SHUTW_NOW))
389 return -1;
390 else
391 return -2;
392}
393
Willy Tarreauc77e7612009-09-13 14:58:00 +0200394/* Try to write character <c> into buffer <buf> after length controls. This
Willy Tarreau9bcc91e2009-10-10 18:01:44 +0200395 * work like buffer_feed2(buf, &c, 1).
Willy Tarreauc77e7612009-09-13 14:58:00 +0200396 * Returns non-zero in case of success, 0 if the buffer was full.
397 * The send limit is automatically adjusted with the amount of data written.
398 */
399static inline int buffer_si_putchar(struct buffer *buf, char c)
400{
401 if (buf->flags & BF_FULL)
402 return 0;
403
Willy Tarreauc77e7612009-09-13 14:58:00 +0200404 *buf->r = c;
405
406 buf->l++;
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100407 if (buf->l >= buffer_max_len(buf))
Willy Tarreauc77e7612009-09-13 14:58:00 +0200408 buf->flags |= BF_FULL;
409
410 buf->r++;
411 if (buf->r - buf->data == buf->size)
412 buf->r -= buf->size;
413
Willy Tarreau31971e52009-09-20 12:07:52 +0200414 if (buf->to_forward >= 1) {
415 if (buf->to_forward != BUF_INFINITE_FORWARD)
416 buf->to_forward--;
Willy Tarreauc77e7612009-09-13 14:58:00 +0200417 buf->send_max++;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200418 buf->flags &= ~BF_OUT_EMPTY;
Willy Tarreauc77e7612009-09-13 14:58:00 +0200419 }
420
421 buf->total++;
422 return 1;
423}
424
Willy Tarreaubaaee002006-06-26 02:48:02 +0200425int buffer_write(struct buffer *buf, const char *msg, int len);
Willy Tarreau9bcc91e2009-10-10 18:01:44 +0200426int buffer_feed2(struct buffer *buf, const char *str, int len);
Willy Tarreau36a5c532009-09-03 07:13:50 +0200427int buffer_si_putchar(struct buffer *buf, char c);
Willy Tarreau4fe7a2e2009-09-01 06:41:32 +0200428int buffer_si_peekline(struct buffer *buf, char *str, int len);
Willy Tarreau4af6f3a2007-03-18 22:36:26 +0100429int buffer_replace(struct buffer *b, char *pos, char *end, const char *str);
430int buffer_replace2(struct buffer *b, char *pos, char *end, const char *str, int len);
431int buffer_insert_line2(struct buffer *b, char *pos, const char *str, int len);
Willy Tarreau8d5d7f22007-01-21 19:16:41 +0100432void buffer_dump(FILE *o, struct buffer *b, int from, int to);
Willy Tarreaub97f1992010-02-25 23:54:31 +0100433void buffer_bounce_realign(struct buffer *buf);
434
Willy Tarreaubaaee002006-06-26 02:48:02 +0200435
Willy Tarreauaeac3192009-08-31 08:09:57 +0200436
437/* writes the chunk <chunk> to buffer <buf>. Returns -1 in case of success,
438 * -2 if it is larger than the buffer size, or the number of bytes available
439 * otherwise. If the chunk has been written, its size is automatically reset
440 * to zero. The send limit is automatically adjusted with the amount of data
441 * written.
442 */
443static inline int buffer_write_chunk(struct buffer *buf, struct chunk *chunk)
444{
445 int ret;
446
447 ret = buffer_write(buf, chunk->str, chunk->len);
448 if (ret == -1)
449 chunk->len = 0;
450 return ret;
451}
452
453/* Try to write chunk <chunk> into buffer <buf> after length controls. This is
454 * the equivalent of buffer_write_chunk() except that to_forward and send_max
455 * are updated and that max_len is respected. Returns -1 in case of success,
456 * -2 if it is larger than the buffer size, or the number of bytes available
457 * otherwise. If the chunk has been written, its size is automatically reset
458 * to zero. The send limit is automatically adjusted with the amount of data
459 * written.
460 */
461static inline int buffer_feed_chunk(struct buffer *buf, struct chunk *chunk)
462{
463 int ret;
464
Willy Tarreau9bcc91e2009-10-10 18:01:44 +0200465 ret = buffer_feed2(buf, chunk->str, chunk->len);
Willy Tarreauaeac3192009-08-31 08:09:57 +0200466 if (ret == -1)
467 chunk->len = 0;
468 return ret;
469}
470
Willy Tarreau9bcc91e2009-10-10 18:01:44 +0200471/* Try to write string <str> into buffer <buf> after length controls. This is
472 * the equivalent of buffer_feed2() except that string length is measured by
473 * the function. Returns -1 in case of success, -2 if it is larger than the
474 * buffer size, or the number of bytes available otherwise. The send limit is
475 * automatically adjusted with the amount of data written.
476 */
477static inline int buffer_feed(struct buffer *buf, const char *str)
478{
479 return buffer_feed2(buf, str, strlen(str));
480}
481
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +0200482static inline void chunk_init(struct chunk *chk, char *str, size_t size) {
483 chk->str = str;
484 chk->len = 0;
485 chk->size = size;
486}
487
488/* report 0 in case of error, 1 if OK. */
Krzysztof Piotr Oledzki6f61b212009-10-04 23:34:15 +0200489static inline int chunk_initlen(struct chunk *chk, char *str, size_t size, int len) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +0200490
Krzysztof Piotr Oledzki6f61b212009-10-04 23:34:15 +0200491 if (size && len > size)
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +0200492 return 0;
493
494 chk->str = str;
495 chk->len = len;
496 chk->size = size;
497
498 return 1;
499}
500
501static inline void chunk_initstr(struct chunk *chk, char *str) {
502 chk->str = str;
503 chk->len = strlen(str);
504 chk->size = 0; /* mark it read-only */
505}
506
507static inline int chunk_strcpy(struct chunk *chk, const char *str) {
508 size_t len;
509
510 len = strlen(str);
511
512 if (unlikely(len > chk->size))
513 return 0;
514
515 chk->len = len;
516 memcpy(chk->str, str, len);
517
518 return 1;
519}
520
521int chunk_printf(struct chunk *chk, const char *fmt, ...)
522 __attribute__ ((format(printf, 2, 3)));
523
Krzysztof Piotr Oledzkiba8d7d32009-10-10 21:06:03 +0200524int chunk_htmlencode(struct chunk *dst, struct chunk *src);
525int chunk_asciiencode(struct chunk *dst, struct chunk *src, char qc);
526
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +0200527static inline void chunk_reset(struct chunk *chk) {
528 chk->str = NULL;
529 chk->len = -1;
530 chk->size = 0;
531}
532
533static inline void chunk_destroy(struct chunk *chk) {
534
535 if (!chk->size)
536 return;
537
538 if (chk->str)
539 free(chk->str);
540
541 chunk_reset(chk);
542}
543
Willy Tarreau0f772532006-12-23 20:51:41 +0100544/*
545 * frees the destination chunk if already allocated, allocates a new string,
546 * and copies the source into it. The pointer to the destination string is
547 * returned, or NULL if the allocation fails or if any pointer is NULL..
548 */
549static inline char *chunk_dup(struct chunk *dst, const struct chunk *src) {
550 if (!dst || !src || !src->str)
551 return NULL;
552 if (dst->str)
553 free(dst->str);
554 dst->len = src->len;
555 dst->str = (char *)malloc(dst->len);
556 memcpy(dst->str, src->str, dst->len);
557 return dst->str;
558}
Willy Tarreaubaaee002006-06-26 02:48:02 +0200559
560#endif /* _PROTO_BUFFERS_H */
561
562/*
563 * Local variables:
564 * c-indent-level: 8
565 * c-basic-offset: 8
566 * End:
567 */