blob: 8ae2a7fe0a07b850f425ba8b914e258ecd18c30c [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 Tarreau74b08c92010-09-08 17:04:31 +020042/* SI-to-buffer functions : buffer_{get,put}_{char,block,string,chunk} */
43int buffer_write(struct buffer *buf, const char *msg, int len);
44int buffer_put_block(struct buffer *buf, const char *str, int len);
45int buffer_put_char(struct buffer *buf, char c);
46int buffer_get_line(struct buffer *buf, char *str, int len);
47int buffer_get_block(struct buffer *buf, char *blk, int len, int offset);
48int buffer_replace(struct buffer *b, char *pos, char *end, const char *str);
49int buffer_replace2(struct buffer *b, char *pos, char *end, const char *str, int len);
50int buffer_insert_line2(struct buffer *b, char *pos, const char *str, int len);
51void buffer_dump(FILE *o, struct buffer *b, int from, int to);
52void buffer_bounce_realign(struct buffer *buf);
53
Willy Tarreau7c3c5412009-12-13 15:53:05 +010054/* Initialize all fields in the buffer. The BF_OUT_EMPTY flags is set. */
Willy Tarreau54469402006-07-29 16:59:06 +020055static inline void buffer_init(struct buffer *buf)
56{
Willy Tarreauf890dc92008-12-13 21:12:26 +010057 buf->send_max = 0;
Willy Tarreau6b66f3e2008-12-14 17:31:54 +010058 buf->to_forward = 0;
Willy Tarreaue393fe22008-08-16 22:18:07 +020059 buf->l = buf->total = 0;
Willy Tarreau3eba98a2009-01-25 13:56:13 +010060 buf->pipe = NULL;
Willy Tarreau2df28e82008-08-17 15:20:19 +020061 buf->analysers = 0;
Willy Tarreaufa7e1022008-10-19 07:30:41 +020062 buf->cons = NULL;
Willy Tarreauba0b63d2009-09-20 08:09:44 +020063 buf->flags = BF_OUT_EMPTY;
Willy Tarreau2df28e82008-08-17 15:20:19 +020064 buf->r = buf->lr = buf->w = buf->data;
Willy Tarreau54469402006-07-29 16:59:06 +020065}
66
Willy Tarreau7c3c5412009-12-13 15:53:05 +010067/* Return the max number of bytes the buffer can contain so that once all the
68 * pending bytes are forwarded, the buffer still has global.tune.maxrewrite
69 * bytes free. The result sits between buf->size - maxrewrite and buf->size.
70 */
71static inline int buffer_max_len(struct buffer *buf)
72{
73 if (buf->to_forward == BUF_INFINITE_FORWARD ||
74 buf->to_forward + buf->send_max >= global.tune.maxrewrite)
75 return buf->size;
76 else
77 return buf->size - global.tune.maxrewrite + buf->to_forward + buf->send_max;
78}
79
Willy Tarreau74b08c92010-09-08 17:04:31 +020080/* Returns true if the buffer's input is already closed */
81static inline int buffer_input_closed(struct buffer *buf)
82{
83 return ((buf->flags & BF_SHUTR) != 0);
84}
85
86/* Returns true if the buffer's output is already closed */
87static inline int buffer_output_closed(struct buffer *buf)
88{
89 return ((buf->flags & BF_SHUTW) != 0);
90}
91
Willy Tarreau2eb52f02008-09-04 09:14:08 +020092/* Check buffer timeouts, and set the corresponding flags. The
93 * likely/unlikely have been optimized for fastest normal path.
Willy Tarreaudd80c6f2008-12-13 22:25:59 +010094 * The read/write timeouts are not set if there was activity on the buffer.
95 * That way, we don't have to update the timeout on every I/O. Note that the
96 * analyser timeout is always checked.
Willy Tarreau2eb52f02008-09-04 09:14:08 +020097 */
98static inline void buffer_check_timeouts(struct buffer *b)
99{
Willy Tarreau86491c32008-12-14 09:04:47 +0100100 if (likely(!(b->flags & (BF_SHUTR|BF_READ_TIMEOUT|BF_READ_ACTIVITY|BF_READ_NOEXP))) &&
Willy Tarreau2eb52f02008-09-04 09:14:08 +0200101 unlikely(tick_is_expired(b->rex, now_ms)))
102 b->flags |= BF_READ_TIMEOUT;
103
Willy Tarreaudd80c6f2008-12-13 22:25:59 +0100104 if (likely(!(b->flags & (BF_SHUTW|BF_WRITE_TIMEOUT|BF_WRITE_ACTIVITY))) &&
Willy Tarreau2eb52f02008-09-04 09:14:08 +0200105 unlikely(tick_is_expired(b->wex, now_ms)))
106 b->flags |= BF_WRITE_TIMEOUT;
107
108 if (likely(!(b->flags & BF_ANA_TIMEOUT)) &&
109 unlikely(tick_is_expired(b->analyse_exp, now_ms)))
110 b->flags |= BF_ANA_TIMEOUT;
111}
112
Willy Tarreau0abebcc2009-01-08 00:09:41 +0100113/* Schedule <bytes> more bytes to be forwarded by the buffer without notifying
114 * the task. Any pending data in the buffer is scheduled to be sent as well,
115 * in the limit of the number of bytes to forward. This must be the only method
116 * to use to schedule bytes to be sent. Directly touching ->to_forward will
117 * cause lockups when send_max goes down to zero if nobody is ready to push the
118 * remaining data.
119 */
Willy Tarreau31971e52009-09-20 12:07:52 +0200120static inline void buffer_forward(struct buffer *buf, unsigned long bytes)
Willy Tarreau0abebcc2009-01-08 00:09:41 +0100121{
Willy Tarreau31971e52009-09-20 12:07:52 +0200122 unsigned long data_left;
Willy Tarreau0abebcc2009-01-08 00:09:41 +0100123
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200124 if (!bytes)
125 return;
Willy Tarreau0abebcc2009-01-08 00:09:41 +0100126 data_left = buf->l - buf->send_max;
Willy Tarreau91aa5772009-09-15 20:32:30 +0200127 if (data_left >= bytes) {
128 buf->send_max += bytes;
Willy Tarreau2d028db2009-09-20 22:56:25 +0200129 buf->flags &= ~BF_OUT_EMPTY;
Willy Tarreau91aa5772009-09-15 20:32:30 +0200130 return;
131 }
Willy Tarreau0abebcc2009-01-08 00:09:41 +0100132
Willy Tarreau0abebcc2009-01-08 00:09:41 +0100133 buf->send_max += data_left;
Willy Tarreau2d028db2009-09-20 22:56:25 +0200134 if (buf->send_max)
135 buf->flags &= ~BF_OUT_EMPTY;
136
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100137 if (buf->to_forward != BUF_INFINITE_FORWARD) {
138 buf->to_forward += bytes - data_left;
139 if (bytes == BUF_INFINITE_FORWARD)
140 buf->to_forward = bytes;
141 }
Willy Tarreau31971e52009-09-20 12:07:52 +0200142
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100143 if (buf->l < buffer_max_len(buf))
144 buf->flags &= ~BF_FULL;
145 else
146 buf->flags |= BF_FULL;
Willy Tarreau0abebcc2009-01-08 00:09:41 +0100147}
148
Willy Tarreaue8a28bf2009-03-08 21:12:04 +0100149/* Schedule all remaining buffer data to be sent. send_max is not touched if it
150 * already covers those data. That permits doing a flush even after a forward,
151 * although not recommended.
152 */
153static inline void buffer_flush(struct buffer *buf)
154{
155 if (buf->send_max < buf->l)
156 buf->send_max = buf->l;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200157 if (buf->send_max)
158 buf->flags &= ~BF_OUT_EMPTY;
Willy Tarreaue8a28bf2009-03-08 21:12:04 +0100159}
160
Willy Tarreau6f0aa472009-03-08 20:33:29 +0100161/* Erase any content from buffer <buf> and adjusts flags accordingly. Note
Willy Tarreau0abebcc2009-01-08 00:09:41 +0100162 * that any spliced data is not affected since we may not have any access to
163 * it.
Willy Tarreaue393fe22008-08-16 22:18:07 +0200164 */
Willy Tarreau6f0aa472009-03-08 20:33:29 +0100165static inline void buffer_erase(struct buffer *buf)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200166{
Willy Tarreauf890dc92008-12-13 21:12:26 +0100167 buf->send_max = 0;
Willy Tarreau6b66f3e2008-12-14 17:31:54 +0100168 buf->to_forward = 0;
Willy Tarreaue09e0ce2007-03-18 16:31:29 +0100169 buf->r = buf->lr = buf->w = buf->data;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200170 buf->l = 0;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200171 buf->flags &= ~(BF_FULL | BF_OUT_EMPTY);
172 if (!buf->pipe)
173 buf->flags |= BF_OUT_EMPTY;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200174}
175
Willy Tarreau9cb8daa2009-09-15 21:22:24 +0200176/* Cut the "tail" of the buffer, which means strip it to the length of unsent
177 * data only, and kill any remaining unsent data. Any scheduled forwarding is
178 * stopped. This is mainly to be used to send error messages after existing
179 * data.
180 */
181static inline void buffer_cut_tail(struct buffer *buf)
182{
183 if (!buf->send_max)
184 return buffer_erase(buf);
185
186 buf->to_forward = 0;
187 if (buf->l == buf->send_max)
188 return;
189
190 buf->l = buf->send_max;
191 buf->r = buf->w + buf->l;
192 if (buf->r >= buf->data + buf->size)
193 buf->r -= buf->size;
194 buf->lr = buf->r;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200195 buf->flags &= ~BF_FULL;
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100196 if (buf->l >= buffer_max_len(buf))
Willy Tarreau9cb8daa2009-09-15 21:22:24 +0200197 buf->flags |= BF_FULL;
198}
199
Willy Tarreaud21e01c2009-12-27 15:45:38 +0100200/* Cut the <n> next unsent bytes of the buffer. The caller must ensure that <n>
201 * is smaller than the actual buffer's length. This is mainly used to remove
202 * empty lines at the beginning of a request or a response.
203 */
204static inline void buffer_ignore(struct buffer *buf, int n)
205{
206 buf->l -= n;
207 buf->w += n;
208 if (buf->w >= buf->data + buf->size)
209 buf->w -= buf->size;
210 buf->flags &= ~BF_FULL;
211 if (buf->l >= buffer_max_len(buf))
212 buf->flags |= BF_FULL;
213}
214
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200215/* marks the buffer as "shutdown" ASAP for reads */
216static inline void buffer_shutr_now(struct buffer *buf)
217{
Willy Tarreaufe3718a2008-11-30 18:14:12 +0100218 buf->flags |= BF_SHUTR_NOW;
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200219}
220
221/* marks the buffer as "shutdown" ASAP for writes */
222static inline void buffer_shutw_now(struct buffer *buf)
223{
224 buf->flags |= BF_SHUTW_NOW;
225}
226
227/* marks the buffer as "shutdown" ASAP in both directions */
228static inline void buffer_abort(struct buffer *buf)
229{
Willy Tarreaufe3718a2008-11-30 18:14:12 +0100230 buf->flags |= BF_SHUTR_NOW | BF_SHUTW_NOW;
Willy Tarreaue4599762010-03-21 23:25:09 +0100231 buf->flags &= ~BF_AUTO_CONNECT;
Willy Tarreaufa7e1022008-10-19 07:30:41 +0200232}
233
Willy Tarreau01bf8672008-12-07 18:03:29 +0100234/* Installs <func> as a hijacker on the buffer <b> for session <s>. The hijack
235 * flag is set, and the function called once. The function is responsible for
236 * clearing the hijack bit. It is possible that the function clears the flag
237 * during this first call.
238 */
239static inline void buffer_install_hijacker(struct session *s,
240 struct buffer *b,
241 void (*func)(struct session *, struct buffer *))
Willy Tarreau72b179a2008-08-28 16:01:32 +0200242{
Willy Tarreau01bf8672008-12-07 18:03:29 +0100243 b->hijacker = func;
244 b->flags |= BF_HIJACK;
245 func(s, b);
Willy Tarreau72b179a2008-08-28 16:01:32 +0200246}
247
Willy Tarreau01bf8672008-12-07 18:03:29 +0100248/* Releases the buffer from hijacking mode. Often used by the hijack function */
Willy Tarreau72b179a2008-08-28 16:01:32 +0200249static inline void buffer_stop_hijack(struct buffer *buf)
250{
251 buf->flags &= ~BF_HIJACK;
252}
253
Willy Tarreau520d95e2009-09-19 21:04:57 +0200254/* allow the consumer to try to establish a new connection. */
255static inline void buffer_auto_connect(struct buffer *buf)
Willy Tarreau3da77c52008-08-29 09:58:42 +0200256{
Willy Tarreau520d95e2009-09-19 21:04:57 +0200257 buf->flags |= BF_AUTO_CONNECT;
Willy Tarreau3da77c52008-08-29 09:58:42 +0200258}
259
Willy Tarreau520d95e2009-09-19 21:04:57 +0200260/* prevent the consumer from trying to establish a new connection, and also
261 * disable auto shutdown forwarding.
262 */
263static inline void buffer_dont_connect(struct buffer *buf)
Willy Tarreau3da77c52008-08-29 09:58:42 +0200264{
Willy Tarreau520d95e2009-09-19 21:04:57 +0200265 buf->flags &= ~(BF_AUTO_CONNECT|BF_AUTO_CLOSE);
Willy Tarreau3da77c52008-08-29 09:58:42 +0200266}
267
Willy Tarreau520d95e2009-09-19 21:04:57 +0200268/* allow the producer to forward shutdown requests */
269static inline void buffer_auto_close(struct buffer *buf)
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100270{
Willy Tarreau520d95e2009-09-19 21:04:57 +0200271 buf->flags |= BF_AUTO_CLOSE;
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100272}
273
Willy Tarreau520d95e2009-09-19 21:04:57 +0200274/* prevent the producer from forwarding shutdown requests */
275static inline void buffer_dont_close(struct buffer *buf)
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100276{
Willy Tarreau520d95e2009-09-19 21:04:57 +0200277 buf->flags &= ~BF_AUTO_CLOSE;
Willy Tarreau0a5d5dd2008-11-23 19:31:35 +0100278}
279
Willy Tarreau90deb182010-01-07 00:20:41 +0100280/* allow the producer to read / poll the input */
281static inline void buffer_auto_read(struct buffer *buf)
282{
283 buf->flags &= ~BF_DONT_READ;
284}
285
286/* prevent the producer from read / poll the input */
287static inline void buffer_dont_read(struct buffer *buf)
288{
289 buf->flags |= BF_DONT_READ;
290}
291
Willy Tarreaubaaee002006-06-26 02:48:02 +0200292/* returns the maximum number of bytes writable at once in this buffer */
Willy Tarreaub17916e2006-10-15 15:17:57 +0200293static inline int buffer_max(const struct buffer *buf)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200294{
Willy Tarreaua07a34e2009-08-16 23:27:46 +0200295 if (buf->l == buf->size)
Willy Tarreaubaaee002006-06-26 02:48:02 +0200296 return 0;
297 else if (buf->r >= buf->w)
Willy Tarreaua07a34e2009-08-16 23:27:46 +0200298 return buf->data + buf->size - buf->r;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200299 else
300 return buf->w - buf->r;
301}
302
Willy Tarreaubaaee002006-06-26 02:48:02 +0200303/*
304 * Tries to realign the given buffer, and returns how many bytes can be written
305 * there at once without overwriting anything.
306 */
307static inline int buffer_realign(struct buffer *buf)
308{
309 if (buf->l == 0) {
310 /* let's realign the buffer to optimize I/O */
Willy Tarreaue09e0ce2007-03-18 16:31:29 +0100311 buf->r = buf->w = buf->lr = buf->data;
Willy Tarreaubaaee002006-06-26 02:48:02 +0200312 }
313 return buffer_max(buf);
314}
315
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200316/*
Willy Tarreau591fedc2010-08-10 15:28:21 +0200317 * Return the maximum amount of bytes that can be written into the buffer in
Willy Tarreau74b08c92010-09-08 17:04:31 +0200318 * one call to buffer_put_*().
Willy Tarreau591fedc2010-08-10 15:28:21 +0200319 */
320static inline int buffer_free_space(struct buffer *buf)
321{
322 return buffer_max_len(buf) - buf->l;
323}
324
325/*
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200326 * Return the max amount of bytes that can be stuffed into the buffer at once.
327 * Note that this may be lower than the actual buffer size when the free space
328 * wraps after the end, so it's preferable to call this function again after
329 * writing. Also note that this function respects max_len.
330 */
331static inline int buffer_contig_space(struct buffer *buf)
332{
333 int ret;
334
335 if (buf->l == 0) {
336 buf->r = buf->w = buf->lr = buf->data;
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100337 ret = buffer_max_len(buf);
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200338 }
339 else if (buf->r > buf->w) {
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100340 ret = buf->data + buffer_max_len(buf) - buf->r;
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200341 }
342 else {
343 ret = buf->w - buf->r;
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100344 if (ret > buffer_max_len(buf))
345 ret = buffer_max_len(buf);
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200346 }
347 return ret;
348}
349
Willy Tarreau591fedc2010-08-10 15:28:21 +0200350/*
351 * Same as above but the caller may pass the value of buffer_max_len(buf) if it
352 * knows it, thus avoiding some calculations.
353 */
354static inline int buffer_contig_space_with_len(struct buffer *buf, int maxlen)
355{
356 int ret;
357
358 if (buf->l == 0) {
359 buf->r = buf->w = buf->lr = buf->data;
360 ret = maxlen;
361 }
362 else if (buf->r > buf->w) {
363 ret = buf->data + maxlen - buf->r;
364 }
365 else {
366 ret = buf->w - buf->r;
367 if (ret > maxlen)
368 ret = maxlen;
369 }
370 return ret;
371}
372
Willy Tarreau4e33d862009-10-11 23:35:10 +0200373/* Return 1 if the buffer has less than 1/4 of its capacity free, otherwise 0 */
374static inline int buffer_almost_full(struct buffer *buf)
375{
Willy Tarreau591fedc2010-08-10 15:28:21 +0200376 if (buffer_free_space(buf) < buf->size / 4)
Willy Tarreau4e33d862009-10-11 23:35:10 +0200377 return 1;
378 return 0;
379}
380
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200381/*
382 * Return the max amount of bytes that can be read from the buffer at once.
383 * Note that this may be lower than the actual buffer length when the data
384 * wrap after the end, so it's preferable to call this function again after
385 * reading. Also note that this function respects the send_max limit.
386 */
387static inline int buffer_contig_data(struct buffer *buf)
388{
389 int ret;
390
391 if (!buf->send_max || !buf->l)
392 return 0;
393
394 if (buf->r > buf->w)
395 ret = buf->r - buf->w;
396 else
397 ret = buf->data + buf->size - buf->w;
398
399 /* limit the amount of outgoing data if required */
400 if (ret > buf->send_max)
401 ret = buf->send_max;
402
403 return ret;
404}
405
406/*
407 * Advance the buffer's read pointer by <len> bytes. This is useful when data
408 * have been read directly from the buffer. It is illegal to call this function
409 * with <len> causing a wrapping at the end of the buffer. It's the caller's
Willy Tarreau2e1dd3d2009-09-23 22:56:07 +0200410 * responsibility to ensure that <len> is never larger than buf->send_max.
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200411 */
412static inline void buffer_skip(struct buffer *buf, int len)
413{
414 buf->w += len;
Willy Tarreau2e1dd3d2009-09-23 22:56:07 +0200415 if (buf->w >= buf->data + buf->size)
416 buf->w -= buf->size; /* wrap around the buffer */
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200417
418 buf->l -= len;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200419 if (!buf->l)
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200420 buf->r = buf->w = buf->lr = buf->data;
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200421
Willy Tarreau7c3c5412009-12-13 15:53:05 +0100422 if (buf->l < buffer_max_len(buf))
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200423 buf->flags &= ~BF_FULL;
424
425 buf->send_max -= len;
Willy Tarreauba0b63d2009-09-20 08:09:44 +0200426 if (!buf->send_max && !buf->pipe)
427 buf->flags |= BF_OUT_EMPTY;
Willy Tarreaufb0e9202009-09-23 23:47:55 +0200428
429 /* notify that some data was written to the SI from the buffer */
430 buf->flags |= BF_WRITE_PARTIAL;
Willy Tarreau2b7addc2009-08-31 07:37:22 +0200431}
Willy Tarreaubaaee002006-06-26 02:48:02 +0200432
Willy Tarreauaeac3192009-08-31 08:09:57 +0200433/* writes the chunk <chunk> to buffer <buf>. Returns -1 in case of success,
434 * -2 if it is larger than the buffer size, or the number of bytes available
435 * otherwise. If the chunk has been written, its size is automatically reset
436 * to zero. The send limit is automatically adjusted with the amount of data
437 * written.
438 */
439static inline int buffer_write_chunk(struct buffer *buf, struct chunk *chunk)
440{
441 int ret;
442
443 ret = buffer_write(buf, chunk->str, chunk->len);
444 if (ret == -1)
445 chunk->len = 0;
446 return ret;
447}
448
Willy Tarreau74b08c92010-09-08 17:04:31 +0200449/* Tries to copy chunk <chunk> into buffer <buf> after length controls.
450 * The send_max and to_forward pointers are updated. If the buffer's input is
451 * closed, -2 is returned. If the block is too large for this buffer, -3 is
452 * returned. If there is not enough room left in the buffer, -1 is returned.
453 * Otherwise the number of bytes copied is returned (0 being a valid number).
454 * Buffer flags FULL, EMPTY and READ_PARTIAL are updated if some data can be
455 * transferred. The chunk's length is updated with the number of bytes sent.
Willy Tarreauaeac3192009-08-31 08:09:57 +0200456 */
Willy Tarreau74b08c92010-09-08 17:04:31 +0200457static inline int buffer_put_chunk(struct buffer *buf, struct chunk *chunk)
Willy Tarreauaeac3192009-08-31 08:09:57 +0200458{
459 int ret;
460
Willy Tarreau74b08c92010-09-08 17:04:31 +0200461 ret = buffer_put_block(buf, chunk->str, chunk->len);
462 if (ret > 0)
463 chunk->len -= ret;
Willy Tarreauaeac3192009-08-31 08:09:57 +0200464 return ret;
465}
466
Willy Tarreau74b08c92010-09-08 17:04:31 +0200467/* Tries to copy string <str> at once into buffer <buf> after length controls.
468 * The send_max and to_forward pointers are updated. If the buffer's input is
469 * closed, -2 is returned. If the block is too large for this buffer, -3 is
470 * returned. If there is not enough room left in the buffer, -1 is returned.
471 * Otherwise the number of bytes copied is returned (0 being a valid number).
472 * Buffer flags FULL, EMPTY and READ_PARTIAL are updated if some data can be
473 * transferred.
474 */
475static inline int buffer_put_string(struct buffer *buf, const char *str)
476{
477 return buffer_put_block(buf, str, strlen(str));
478}
479
480/*
481 * Return one char from the buffer. If the buffer is empty and closed, return -2.
482 * If the buffer is just empty, return -1. The buffer's pointer is not advanced,
483 * it's up to the caller to call buffer_skip(buf, 1) when it has consumed the char.
484 * Also note that this function respects the send_max limit.
485 */
486static inline int buffer_get_char(struct buffer *buf)
487{
488 /* closed or empty + imminent close = -2; empty = -1 */
489 if (unlikely(buf->flags & (BF_OUT_EMPTY|BF_SHUTW))) {
490 if (buf->flags & (BF_SHUTW|BF_SHUTW_NOW))
491 return -2;
492 return -1;
493 }
494 return *buf->w;
495}
496
497
498/* DEPRECATED, just provided for compatibility, use buffer_put_chunk() instead !!!
499 * returns >= 0 if the buffer is too small to hold the message, -1 if the
500 * transfer was OK, -2 in case of failure.
501 */
502static inline int buffer_feed_chunk(struct buffer *buf, struct chunk *msg)
503{
504 int ret = buffer_put_chunk(buf, msg);
505 if (ret >= 0) /* transfer OK */
506 return -1;
507 if (ret == -1) /* missing room */
508 return 1;
509 /* failure */
510 return -2;
511}
512
513/* DEPRECATED, just provided for compatibility, use buffer_put_string() instead !!!
514 * returns >= 0 if the buffer is too small to hold the message, -1 if the
515 * transfer was OK, -2 in case of failure.
Willy Tarreau9bcc91e2009-10-10 18:01:44 +0200516 */
517static inline int buffer_feed(struct buffer *buf, const char *str)
518{
Willy Tarreau74b08c92010-09-08 17:04:31 +0200519 int ret = buffer_put_string(buf, str);
520 if (ret >= 0) /* transfer OK */
521 return -1;
522 if (ret == -1) /* missing room */
523 return 1;
524 /* failure */
525 return -2;
Willy Tarreau9bcc91e2009-10-10 18:01:44 +0200526}
527
Willy Tarreau74b08c92010-09-08 17:04:31 +0200528/*
529 *
530 * Functions below are used to manage chunks
531 *
532 */
533
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +0200534static inline void chunk_init(struct chunk *chk, char *str, size_t size) {
535 chk->str = str;
536 chk->len = 0;
537 chk->size = size;
538}
539
540/* report 0 in case of error, 1 if OK. */
Krzysztof Piotr Oledzki6f61b212009-10-04 23:34:15 +0200541static inline int chunk_initlen(struct chunk *chk, char *str, size_t size, int len) {
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +0200542
Krzysztof Piotr Oledzki6f61b212009-10-04 23:34:15 +0200543 if (size && len > size)
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +0200544 return 0;
545
546 chk->str = str;
547 chk->len = len;
548 chk->size = size;
549
550 return 1;
551}
552
553static inline void chunk_initstr(struct chunk *chk, char *str) {
554 chk->str = str;
555 chk->len = strlen(str);
556 chk->size = 0; /* mark it read-only */
557}
558
559static inline int chunk_strcpy(struct chunk *chk, const char *str) {
560 size_t len;
561
562 len = strlen(str);
563
564 if (unlikely(len > chk->size))
565 return 0;
566
567 chk->len = len;
568 memcpy(chk->str, str, len);
569
570 return 1;
571}
572
573int chunk_printf(struct chunk *chk, const char *fmt, ...)
574 __attribute__ ((format(printf, 2, 3)));
575
Krzysztof Piotr Oledzkiba8d7d32009-10-10 21:06:03 +0200576int chunk_htmlencode(struct chunk *dst, struct chunk *src);
577int chunk_asciiencode(struct chunk *dst, struct chunk *src, char qc);
578
Krzysztof Piotr Oledzki78abe612009-09-27 13:23:20 +0200579static inline void chunk_reset(struct chunk *chk) {
580 chk->str = NULL;
581 chk->len = -1;
582 chk->size = 0;
583}
584
585static inline void chunk_destroy(struct chunk *chk) {
586
587 if (!chk->size)
588 return;
589
590 if (chk->str)
591 free(chk->str);
592
593 chunk_reset(chk);
594}
595
Willy Tarreau0f772532006-12-23 20:51:41 +0100596/*
597 * frees the destination chunk if already allocated, allocates a new string,
598 * and copies the source into it. The pointer to the destination string is
599 * returned, or NULL if the allocation fails or if any pointer is NULL..
600 */
601static inline char *chunk_dup(struct chunk *dst, const struct chunk *src) {
602 if (!dst || !src || !src->str)
603 return NULL;
604 if (dst->str)
605 free(dst->str);
606 dst->len = src->len;
607 dst->str = (char *)malloc(dst->len);
608 memcpy(dst->str, src->str, dst->len);
609 return dst->str;
610}
Willy Tarreaubaaee002006-06-26 02:48:02 +0200611
612#endif /* _PROTO_BUFFERS_H */
613
614/*
615 * Local variables:
616 * c-indent-level: 8
617 * c-basic-offset: 8
618 * End:
619 */