mirror of
https://github.com/haproxy/haproxy.git
synced 2026-02-20 00:10:41 -05:00
MAJOR: buffers: replace buf->r with buf->p + buf->i
This change gets rid of buf->r which is always equal to buf->p + buf->i. It removed some wrapping detection at a number of places, but required addition of new relative offset computations at other locations. A large number of places can be simplified now with extreme care, since most of the time, either the pointer has to be computed once or we need a difference between the old ->w and old ->r to compute free space. The cleanup will probably happen with the rewrite of the buffer_input_* and buffer_output_* functions anyway. buf->lr still has to move to the struct http_msg and be relative to buf->p for the rework to be complete.
This commit is contained in:
parent
89fa706d39
commit
363a5bb152
6 changed files with 88 additions and 118 deletions
|
|
@ -62,7 +62,7 @@ static inline void buffer_init(struct buffer *buf)
|
|||
buf->analysers = 0;
|
||||
buf->cons = NULL;
|
||||
buf->flags = BF_OUT_EMPTY;
|
||||
buf->r = buf->lr = buf->p = buf->data;
|
||||
buf->lr = buf->p = buf->data;
|
||||
}
|
||||
|
||||
/*****************************************************************/
|
||||
|
|
@ -158,45 +158,25 @@ static inline int buffer_contig_area(const struct buffer *buf, const char *start
|
|||
}
|
||||
|
||||
/* Return the amount of bytes that can be written into the buffer at once,
|
||||
* including reserved space which may be overwritten. This version is optimized
|
||||
* to reduce the amount of operations but it's not easy to understand as it is.
|
||||
* Drawing a buffer with wrapping data on a paper helps a lot.
|
||||
* including reserved space which may be overwritten.
|
||||
*/
|
||||
static inline int buffer_contig_space(const struct buffer *buf)
|
||||
{
|
||||
int space_from_end = buffer_len(buf) - (buf->r - buf->data);
|
||||
if (space_from_end < 0) /* data does not wrap */
|
||||
space_from_end = buf->r - buf->data;
|
||||
return buf->size - space_from_end;
|
||||
const char *left, *right;
|
||||
|
||||
if (buf->data + buf->o <= buf->p)
|
||||
right = buf->data + buf->size;
|
||||
else
|
||||
right = buf->p + buf->size - buf->o;
|
||||
|
||||
left = buffer_wrap_add(buf, buf->p + buf->i);
|
||||
return right - left;
|
||||
}
|
||||
|
||||
|
||||
/* Return the amount of bytes that can be written into the buffer at once,
|
||||
* excluding reserved space, which is preserved. Same comment as above for
|
||||
* the optimization leading to hardly understandable code.
|
||||
*/
|
||||
static inline int buffer_contig_space_res(const struct buffer *buf)
|
||||
{
|
||||
/* Proceed differently if the buffer is full, partially used or empty.
|
||||
* The hard situation is when it's partially used and either data or
|
||||
* reserved space wraps at the end.
|
||||
*/
|
||||
int res = buffer_reserved(buf);
|
||||
int spare = buf->size - res;
|
||||
|
||||
if (buffer_len(buf) >= spare)
|
||||
spare = 0;
|
||||
else if (buffer_len(buf)) {
|
||||
spare = buffer_wrap_sub(buf, buf->p - buf->o) - res - buf->r;
|
||||
if (spare <= 0)
|
||||
spare += buf->size;
|
||||
spare = buffer_contig_area(buf, buf->r, spare);
|
||||
}
|
||||
return spare;
|
||||
}
|
||||
|
||||
/* Same as above, but lets the caller pass the pre-computed value of
|
||||
* buffer_reserved() in <res> if it already knows it, to save some
|
||||
* computations.
|
||||
* excluding the amount of reserved space passed in <res>, which is
|
||||
* preserved.
|
||||
*/
|
||||
static inline int buffer_contig_space_with_res(const struct buffer *buf, int res)
|
||||
{
|
||||
|
|
@ -209,14 +189,22 @@ static inline int buffer_contig_space_with_res(const struct buffer *buf, int res
|
|||
if (buffer_len(buf) >= spare)
|
||||
spare = 0;
|
||||
else if (buffer_len(buf)) {
|
||||
spare = buffer_wrap_sub(buf, buf->p - buf->o) - res - buf->r;
|
||||
if (spare <= 0)
|
||||
spare += buf->size;
|
||||
spare = buffer_contig_area(buf, buf->r, spare);
|
||||
spare = buffer_contig_space(buf) - res;
|
||||
if (spare < 0)
|
||||
spare = 0;
|
||||
}
|
||||
return spare;
|
||||
}
|
||||
|
||||
|
||||
/* Return the amount of bytes that can be written into the buffer at once,
|
||||
* excluding reserved space, which is preserved.
|
||||
*/
|
||||
static inline int buffer_contig_space_res(const struct buffer *buf)
|
||||
{
|
||||
return buffer_contig_space_with_res(buf, buffer_reserved(buf));
|
||||
}
|
||||
|
||||
/* Normalizes a pointer which is supposed to be relative to the beginning of a
|
||||
* buffer, so that wrapping is correctly handled. The intent is to use this
|
||||
* when increasing a pointer. Note that the wrapping test is only performed
|
||||
|
|
@ -260,7 +248,8 @@ static inline int buffer_pending(const struct buffer *buf)
|
|||
static inline int buffer_work_area(const struct buffer *buf, const char *end)
|
||||
{
|
||||
end = buffer_pointer(buf, end);
|
||||
if (end == buf->r) /* pointer exactly at end, lets push forwards */
|
||||
if (end == buffer_wrap_add(buf, buf->p + buf->i))
|
||||
/* pointer exactly at end, lets push forwards */
|
||||
end = buffer_wrap_sub(buf, buf->p - buf->o);
|
||||
return buffer_count(buf, buf->p, end);
|
||||
}
|
||||
|
|
@ -312,7 +301,7 @@ static inline void buffer_check_timeouts(struct buffer *b)
|
|||
*/
|
||||
static inline void buffer_flush(struct buffer *buf)
|
||||
{
|
||||
buf->p = buf->r;
|
||||
buf->p = buffer_wrap_add(buf, buf->p + buf->i);
|
||||
buf->o += buf->i;
|
||||
buf->i = 0;
|
||||
if (buf->o)
|
||||
|
|
@ -328,7 +317,7 @@ static inline void buffer_erase(struct buffer *buf)
|
|||
buf->o = 0;
|
||||
buf->i = 0;
|
||||
buf->to_forward = 0;
|
||||
buf->r = buf->lr = buf->p = buf->data;
|
||||
buf->lr = buf->p = buf->data;
|
||||
buf->flags &= ~(BF_FULL | BF_OUT_EMPTY);
|
||||
if (!buf->pipe)
|
||||
buf->flags |= BF_OUT_EMPTY;
|
||||
|
|
@ -349,10 +338,7 @@ static inline void buffer_cut_tail(struct buffer *buf)
|
|||
return;
|
||||
|
||||
buf->i = 0;
|
||||
buf->r = buf->p;
|
||||
if (buf->r >= buf->data + buf->size)
|
||||
buf->r -= buf->size;
|
||||
buf->lr = buf->r;
|
||||
buf->lr = buf->p;
|
||||
buf->flags &= ~BF_FULL;
|
||||
if (buffer_len(buf) >= buffer_max_len(buf))
|
||||
buf->flags |= BF_FULL;
|
||||
|
|
@ -456,7 +442,7 @@ static inline int buffer_realign(struct buffer *buf)
|
|||
{
|
||||
if (!(buf->i | buf->o)) {
|
||||
/* let's realign the buffer to optimize I/O */
|
||||
buf->r = buf->p = buf->lr = buf->data;
|
||||
buf->p = buf->lr = buf->data;
|
||||
}
|
||||
return buffer_contig_space(buf);
|
||||
}
|
||||
|
|
@ -471,7 +457,7 @@ static inline void buffer_skip(struct buffer *buf, int len)
|
|||
{
|
||||
buf->o -= len;
|
||||
if (buffer_len(buf) == 0)
|
||||
buf->r = buf->p = buf->lr = buf->data;
|
||||
buf->p = buf->lr = buf->data;
|
||||
|
||||
if (buffer_len(buf) < buffer_max_len(buf))
|
||||
buf->flags &= ~BF_FULL;
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ struct buffer {
|
|||
int wex; /* expiration date for a write or connect, in ticks */
|
||||
int rto; /* read timeout, in ticks */
|
||||
int wto; /* write timeout, in ticks */
|
||||
char *r, *lr; /* read ptr, last read */
|
||||
char *lr; /* last read read */
|
||||
char *p; /* buffer's start pointer, separates in and out data */
|
||||
unsigned int size; /* buffer size in bytes */
|
||||
unsigned int i; /* number of input bytes pending for analysis in the buffer */
|
||||
|
|
|
|||
|
|
@ -96,6 +96,8 @@ unsigned long long buffer_forward(struct buffer *buf, unsigned long long bytes)
|
|||
* success, -2 if the message is larger than the buffer size, or the number of
|
||||
* bytes available otherwise. The send limit is automatically adjusted with the
|
||||
* amount of data written. FIXME-20060521: handle unaligned data.
|
||||
* Note: this function appends data to the buffer's output and possibly overwrites
|
||||
* any pending input data which are assumed not to exist.
|
||||
*/
|
||||
int buffer_write(struct buffer *buf, const char *msg, int len)
|
||||
{
|
||||
|
|
@ -118,10 +120,9 @@ int buffer_write(struct buffer *buf, const char *msg, int len)
|
|||
if (len > max)
|
||||
return max;
|
||||
|
||||
memcpy(buf->r, msg, len);
|
||||
memcpy(buf->p, msg, len);
|
||||
buf->o += len;
|
||||
buf->p = buffer_wrap_add(buf, buf->p + len);
|
||||
buf->r = buffer_wrap_add(buf, buf->r + len);
|
||||
buf->total += len;
|
||||
|
||||
buf->flags &= ~(BF_OUT_EMPTY|BF_FULL);
|
||||
|
|
@ -146,17 +147,13 @@ int buffer_put_char(struct buffer *buf, char c)
|
|||
if (buf->flags & BF_FULL)
|
||||
return -1;
|
||||
|
||||
*buf->r = c;
|
||||
*buffer_wrap_add(buf, buf->p + buf->i) = c;
|
||||
|
||||
buf->i++;
|
||||
if (buffer_len(buf) >= buffer_max_len(buf))
|
||||
buf->flags |= BF_FULL;
|
||||
buf->flags |= BF_READ_PARTIAL;
|
||||
|
||||
buf->r++;
|
||||
if (buf->r - buf->data == buf->size)
|
||||
buf->r -= buf->size;
|
||||
|
||||
if (buf->to_forward >= 1) {
|
||||
if (buf->to_forward != BUF_INFINITE_FORWARD)
|
||||
buf->to_forward--;
|
||||
|
|
@ -201,12 +198,11 @@ int buffer_put_block(struct buffer *buf, const char *blk, int len)
|
|||
|
||||
/* OK so the data fits in the buffer in one or two blocks */
|
||||
max = buffer_contig_space_with_res(buf, buf->size - max);
|
||||
memcpy(buf->r, blk, MIN(len, max));
|
||||
memcpy(buffer_wrap_add(buf, buf->p + buf->i), blk, MIN(len, max));
|
||||
if (len > max)
|
||||
memcpy(buf->data, blk + max, len - max);
|
||||
|
||||
buf->i += len;
|
||||
buf->r += len;
|
||||
buf->total += len;
|
||||
if (buf->to_forward) {
|
||||
unsigned long fwd = len;
|
||||
|
|
@ -221,9 +217,6 @@ int buffer_put_block(struct buffer *buf, const char *blk, int len)
|
|||
buf->flags &= ~BF_OUT_EMPTY;
|
||||
}
|
||||
|
||||
if (buf->r >= buf->data + buf->size)
|
||||
buf->r -= buf->size;
|
||||
|
||||
buf->flags &= ~BF_FULL;
|
||||
if (buffer_len(buf) >= buffer_max_len(buf))
|
||||
buf->flags |= BF_FULL;
|
||||
|
|
@ -335,28 +328,28 @@ int buffer_replace2(struct buffer *b, char *pos, char *end, const char *str, int
|
|||
|
||||
delta = len - (end - pos);
|
||||
|
||||
if (delta + b->r >= b->data + b->size)
|
||||
if (delta + buffer_wrap_add(b, b->p + b->i) >= b->data + b->size)
|
||||
return 0; /* no space left */
|
||||
|
||||
if (delta + b->r > buffer_wrap_sub(b, b->p - b->o) &&
|
||||
buffer_wrap_sub(b, b->p - b->o) >= b->r && buffer_not_empty(b))
|
||||
if (buffer_not_empty(b) &&
|
||||
delta + buffer_wrap_add(b, b->p + b->i) > buffer_wrap_sub(b, b->p - b->o) &&
|
||||
buffer_wrap_sub(b, b->p - b->o) >= buffer_wrap_add(b, b->p + b->i))
|
||||
return 0; /* no space left before wrapping data */
|
||||
|
||||
/* first, protect the end of the buffer */
|
||||
memmove(end + delta, end, b->r - end);
|
||||
memmove(end + delta, end, buffer_wrap_add(b, b->p + b->i) - end);
|
||||
|
||||
/* now, copy str over pos */
|
||||
if (len)
|
||||
memcpy(pos, str, len);
|
||||
|
||||
/* we only move data after the displaced zone */
|
||||
if (b->r > pos) b->r += delta;
|
||||
if (b->lr > pos) b->lr += delta;
|
||||
b->i += delta;
|
||||
|
||||
b->flags &= ~BF_FULL;
|
||||
if (buffer_len(b) == 0)
|
||||
b->r = b->p = b->lr = b->data;
|
||||
b->p = b->lr = b->data;
|
||||
if (buffer_len(b) >= buffer_max_len(b))
|
||||
b->flags |= BF_FULL;
|
||||
|
||||
|
|
@ -378,11 +371,11 @@ int buffer_insert_line2(struct buffer *b, char *pos, const char *str, int len)
|
|||
|
||||
delta = len + 2;
|
||||
|
||||
if (delta + b->r >= b->data + b->size)
|
||||
if (delta + buffer_wrap_add(b, b->p + b->i) >= b->data + b->size)
|
||||
return 0; /* no space left */
|
||||
|
||||
/* first, protect the end of the buffer */
|
||||
memmove(pos + delta, pos, b->r - pos);
|
||||
memmove(pos + delta, pos, buffer_wrap_add(b, b->p + b->i) - pos);
|
||||
|
||||
/* now, copy str over pos */
|
||||
if (len && str) {
|
||||
|
|
@ -392,7 +385,6 @@ int buffer_insert_line2(struct buffer *b, char *pos, const char *str, int len)
|
|||
}
|
||||
|
||||
/* we only move data after the displaced zone */
|
||||
if (b->r > pos) b->r += delta;
|
||||
if (b->lr > pos) b->lr += delta;
|
||||
b->i += delta;
|
||||
|
||||
|
|
@ -445,11 +437,11 @@ void buffer_bounce_realign(struct buffer *buf)
|
|||
* empty area is either between buf->r and from or before from or
|
||||
* after buf->r.
|
||||
*/
|
||||
if (from > buf->r) {
|
||||
if (to >= buf->r && to < from)
|
||||
if (from > buffer_wrap_add(buf, buf->p + buf->i)) {
|
||||
if (to >= buffer_wrap_add(buf, buf->p + buf->i) && to < from)
|
||||
break;
|
||||
} else if (from < buf->r) {
|
||||
if (to < from || to >= buf->r)
|
||||
} else if (from < buffer_wrap_add(buf, buf->p + buf->i)) {
|
||||
if (to < from || to >= buffer_wrap_add(buf, buf->p + buf->i))
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -577,8 +569,8 @@ int chunk_asciiencode(struct chunk *dst, struct chunk *src, char qc) {
|
|||
void buffer_dump(FILE *o, struct buffer *b, int from, int to)
|
||||
{
|
||||
fprintf(o, "Dumping buffer %p\n", b);
|
||||
fprintf(o, " data=%p o=%d i=%d r=%p p=%p lr=%p\n",
|
||||
b->data, b->o, b->i, b->r, b->p, b->lr);
|
||||
fprintf(o, " data=%p o=%d i=%d p=%p lr=%p\n",
|
||||
b->data, b->o, b->i, b->p, b->lr);
|
||||
|
||||
if (!to || to > buffer_len(b))
|
||||
to = buffer_len(b);
|
||||
|
|
|
|||
|
|
@ -3389,12 +3389,11 @@ static int stats_dump_full_sess_to_buffer(struct stream_interface *si)
|
|||
|
||||
chunk_printf(&msg,
|
||||
" wex=%s\n"
|
||||
" data=%p r=%d p=%d lr=%d total=%lld\n",
|
||||
" data=%p p=%d lr=%d total=%lld\n",
|
||||
sess->req->wex ?
|
||||
human_time(TICKS_TO_MS(sess->req->wex - now_ms),
|
||||
TICKS_TO_MS(1000)) : "<NEVER>",
|
||||
sess->req->data,
|
||||
(int)(sess->req->r - sess->req->data),
|
||||
(int)(sess->req->p - sess->req->data),
|
||||
(int)(sess->req->lr - sess->req->data),
|
||||
sess->req->total);
|
||||
|
|
@ -3419,12 +3418,11 @@ static int stats_dump_full_sess_to_buffer(struct stream_interface *si)
|
|||
|
||||
chunk_printf(&msg,
|
||||
" wex=%s\n"
|
||||
" data=%p r=%d p=%d lr=%d total=%lld\n",
|
||||
" data=%p p=%d lr=%d total=%lld\n",
|
||||
sess->rep->wex ?
|
||||
human_time(TICKS_TO_MS(sess->rep->wex - now_ms),
|
||||
TICKS_TO_MS(1000)) : "<NEVER>",
|
||||
sess->rep->data,
|
||||
(int)(sess->rep->r - sess->rep->data),
|
||||
(int)(sess->rep->p - sess->rep->data),
|
||||
(int)(sess->rep->lr - sess->rep->data),
|
||||
sess->rep->total);
|
||||
|
|
|
|||
|
|
@ -1279,7 +1279,7 @@ void http_msg_analyzer(struct buffer *buf, struct http_msg *msg, struct hdr_idx
|
|||
|
||||
state = msg->msg_state;
|
||||
ptr = buf->lr;
|
||||
end = buf->r;
|
||||
end = buffer_wrap_add(buf, buf->p + buf->i);
|
||||
|
||||
if (unlikely(ptr >= end))
|
||||
goto http_msg_ood;
|
||||
|
|
@ -1753,6 +1753,7 @@ int http_parse_chunk_size(struct buffer *buf, struct http_msg *msg)
|
|||
{
|
||||
char *ptr = buf->lr;
|
||||
char *end = buf->data + buf->size;
|
||||
char *stop = buffer_wrap_add(buf, buf->p + buf->i);
|
||||
unsigned int chunk = 0;
|
||||
|
||||
/* The chunk size is in the following form, though we are only
|
||||
|
|
@ -1761,7 +1762,7 @@ int http_parse_chunk_size(struct buffer *buf, struct http_msg *msg)
|
|||
*/
|
||||
while (1) {
|
||||
int c;
|
||||
if (ptr == buf->r)
|
||||
if (ptr == stop)
|
||||
return 0;
|
||||
c = hex2i(*ptr);
|
||||
if (c < 0) /* not a hex digit anymore */
|
||||
|
|
@ -1780,7 +1781,7 @@ int http_parse_chunk_size(struct buffer *buf, struct http_msg *msg)
|
|||
while (http_is_spht[(unsigned char)*ptr]) {
|
||||
if (++ptr >= end)
|
||||
ptr = buf->data;
|
||||
if (ptr == buf->r)
|
||||
if (ptr == stop)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1793,7 +1794,7 @@ int http_parse_chunk_size(struct buffer *buf, struct http_msg *msg)
|
|||
if (likely(*ptr == '\r')) {
|
||||
if (++ptr >= end)
|
||||
ptr = buf->data;
|
||||
if (ptr == buf->r)
|
||||
if (ptr == stop)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1808,13 +1809,13 @@ int http_parse_chunk_size(struct buffer *buf, struct http_msg *msg)
|
|||
/* chunk extension, ends at next CRLF */
|
||||
if (++ptr >= end)
|
||||
ptr = buf->data;
|
||||
if (ptr == buf->r)
|
||||
if (ptr == stop)
|
||||
return 0;
|
||||
|
||||
while (!HTTP_IS_CRLF(*ptr)) {
|
||||
if (++ptr >= end)
|
||||
ptr = buf->data;
|
||||
if (ptr == buf->r)
|
||||
if (ptr == stop)
|
||||
return 0;
|
||||
}
|
||||
/* we have a CRLF now, loop above */
|
||||
|
|
@ -1860,11 +1861,12 @@ int http_forward_trailers(struct buffer *buf, struct http_msg *msg)
|
|||
while (1) {
|
||||
char *p1 = NULL, *p2 = NULL;
|
||||
char *ptr = buf->lr;
|
||||
char *stop = buffer_wrap_add(buf, buf->p + buf->i);
|
||||
int bytes;
|
||||
|
||||
/* scan current line and stop at LF or CRLF */
|
||||
while (1) {
|
||||
if (ptr == buf->r)
|
||||
if (ptr == stop)
|
||||
return 0;
|
||||
|
||||
if (*ptr == '\n') {
|
||||
|
|
@ -1974,10 +1976,10 @@ void http_buffer_heavy_realign(struct buffer *buf, struct http_msg *msg)
|
|||
if (buf->i) {
|
||||
int block1 = buf->i;
|
||||
int block2 = 0;
|
||||
if (buf->r <= buf->p) {
|
||||
if (buf->p + buf->i > buf->data + buf->size) {
|
||||
/* non-contiguous block */
|
||||
block1 = buf->data + buf->size - buf->p;
|
||||
block2 = buf->r - buf->data;
|
||||
block2 = buf->p + buf->i - (buf->data + buf->size);
|
||||
}
|
||||
if (block2)
|
||||
memcpy(swap_buffer, buf->data, block2);
|
||||
|
|
@ -1989,7 +1991,6 @@ void http_buffer_heavy_realign(struct buffer *buf, struct http_msg *msg)
|
|||
/* adjust all known pointers */
|
||||
buf->p = buf->data;
|
||||
buf->lr += off; if (buf->lr >= end) buf->lr -= buf->size;
|
||||
buf->r += off; if (buf->r >= end) buf->r -= buf->size;
|
||||
msg->sol += off; if (msg->sol >= end) msg->sol -= buf->size;
|
||||
msg->eol += off; if (msg->eol >= end) msg->eol -= buf->size;
|
||||
|
||||
|
|
@ -2066,8 +2067,8 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit)
|
|||
if (buffer_not_empty(req) && msg->msg_state < HTTP_MSG_ERROR) {
|
||||
if ((txn->flags & TX_NOT_FIRST) &&
|
||||
unlikely((req->flags & BF_FULL) ||
|
||||
req->r < req->lr ||
|
||||
req->r > req->data + req->size - global.tune.maxrewrite)) {
|
||||
buffer_wrap_add(req, req->p + req->i) < req->lr ||
|
||||
buffer_wrap_add(req, req->p + req->i) > req->data + req->size - global.tune.maxrewrite)) {
|
||||
if (req->o) {
|
||||
if (req->flags & (BF_SHUTW|BF_SHUTW_NOW|BF_WRITE_ERROR|BF_WRITE_TIMEOUT))
|
||||
goto failed_keep_alive;
|
||||
|
|
@ -2076,7 +2077,8 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit)
|
|||
req->flags |= BF_READ_DONTWAIT; /* try to get back here ASAP */
|
||||
return 0;
|
||||
}
|
||||
if (req->r < req->lr || req->r > req->data + req->size - global.tune.maxrewrite)
|
||||
if (buffer_wrap_add(req, req->p + req->i) < req->lr ||
|
||||
buffer_wrap_add(req, req->p + req->i) > req->data + req->size - global.tune.maxrewrite)
|
||||
http_buffer_heavy_realign(req, msg);
|
||||
}
|
||||
|
||||
|
|
@ -2089,8 +2091,8 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit)
|
|||
*/
|
||||
if ((txn->flags & TX_NOT_FIRST) &&
|
||||
unlikely((s->rep->flags & BF_FULL) ||
|
||||
s->rep->r < s->rep->lr ||
|
||||
s->rep->r > s->rep->data + s->rep->size - global.tune.maxrewrite)) {
|
||||
buffer_wrap_add(s->rep, s->rep->p + s->rep->i) < s->rep->lr ||
|
||||
buffer_wrap_add(s->rep, s->rep->p + s->rep->i) > s->rep->data + s->rep->size - global.tune.maxrewrite)) {
|
||||
if (s->rep->o) {
|
||||
if (s->rep->flags & (BF_SHUTW|BF_SHUTW_NOW|BF_WRITE_ERROR|BF_WRITE_TIMEOUT))
|
||||
goto failed_keep_alive;
|
||||
|
|
@ -2102,7 +2104,7 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit)
|
|||
}
|
||||
}
|
||||
|
||||
if (likely(req->lr < req->r))
|
||||
if (likely(req->lr < buffer_wrap_add(req, req->p + req->i)))
|
||||
http_msg_analyzer(req, msg, &txn->hdr_idx);
|
||||
}
|
||||
|
||||
|
|
@ -2591,7 +2593,7 @@ int http_process_req_stat_post(struct stream_interface *si, struct http_txn *txn
|
|||
si->applet.ctx.stats.st_code = STAT_STATUS_EXCD;
|
||||
return 1;
|
||||
}
|
||||
else if (end_params > req->data + req->i) {
|
||||
else if (end_params > req->p + req->i) {
|
||||
/* we need more data */
|
||||
si->applet.ctx.stats.st_code = STAT_STATUS_NONE;
|
||||
return 0;
|
||||
|
|
@ -3823,7 +3825,7 @@ void http_end_txn_clean_session(struct session *s)
|
|||
if (s->req->i) {
|
||||
if (s->rep->o &&
|
||||
!(s->rep->flags & BF_FULL) &&
|
||||
s->rep->r <= s->rep->data + s->rep->size - global.tune.maxrewrite)
|
||||
buffer_wrap_add(s->rep, s->rep->p + s->rep->i) <= s->rep->data + s->rep->size - global.tune.maxrewrite)
|
||||
s->rep->flags |= BF_EXPECT_MORE;
|
||||
}
|
||||
|
||||
|
|
@ -4483,8 +4485,8 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit)
|
|||
*/
|
||||
if (buffer_not_empty(rep) && msg->msg_state < HTTP_MSG_ERROR) {
|
||||
if (unlikely((rep->flags & BF_FULL) ||
|
||||
rep->r < rep->lr ||
|
||||
rep->r > rep->data + rep->size - global.tune.maxrewrite)) {
|
||||
buffer_wrap_add(rep, rep->p + rep->i) < rep->lr ||
|
||||
buffer_wrap_add(rep, rep->p + rep->i) > rep->data + rep->size - global.tune.maxrewrite)) {
|
||||
if (rep->o) {
|
||||
/* some data has still not left the buffer, wake us once that's done */
|
||||
if (rep->flags & (BF_SHUTW|BF_SHUTW_NOW|BF_WRITE_ERROR|BF_WRITE_TIMEOUT))
|
||||
|
|
@ -4497,7 +4499,7 @@ int http_wait_for_response(struct session *s, struct buffer *rep, int an_bit)
|
|||
http_buffer_heavy_realign(rep, msg);
|
||||
}
|
||||
|
||||
if (likely(rep->lr < rep->r))
|
||||
if (likely(rep->lr < buffer_wrap_add(rep, rep->p + rep->i)))
|
||||
http_msg_analyzer(rep, msg, &txn->hdr_idx);
|
||||
}
|
||||
|
||||
|
|
@ -7231,15 +7233,15 @@ void http_capture_bad_message(struct error_snapshot *es, struct session *s,
|
|||
struct buffer *buf, struct http_msg *msg,
|
||||
int state, struct proxy *other_end)
|
||||
{
|
||||
if (buf->r <= (buf->data + msg->som)) { /* message wraps */
|
||||
if (buffer_wrap_add(buf, buf->p + buf->i) <= (buf->data + msg->som)) { /* message wraps */
|
||||
int len1 = buf->size - msg->som;
|
||||
es->len = buf->r - (buf->data + msg->som) + buf->size;
|
||||
es->len = buffer_wrap_add(buf, buf->p + buf->i) - (buf->data + msg->som) + buf->size;
|
||||
memcpy(es->buf, buf->data + msg->som, MIN(len1, sizeof(es->buf)));
|
||||
if (es->len > len1 && len1 < sizeof(es->buf))
|
||||
memcpy(es->buf, buf->data, MIN(es->len, sizeof(es->buf)) - len1);
|
||||
}
|
||||
else {
|
||||
es->len = buf->r - (buf->data + msg->som);
|
||||
es->len = buffer_wrap_add(buf, buf->p + buf->i) - (buf->data + msg->som);
|
||||
memcpy(es->buf, buf->data + msg->som, MIN(es->len, sizeof(es->buf)));
|
||||
}
|
||||
|
||||
|
|
@ -7444,10 +7446,8 @@ void http_reset_txn(struct session *s)
|
|||
* a HEAD with some data, or sending more than the advertised
|
||||
* content-length.
|
||||
*/
|
||||
if (unlikely(s->rep->i)) {
|
||||
if (unlikely(s->rep->i))
|
||||
s->rep->i = 0;
|
||||
s->rep->r = s->rep->p;
|
||||
}
|
||||
|
||||
s->req->rto = s->fe->timeout.client;
|
||||
s->req->wto = TICK_ETERNITY;
|
||||
|
|
@ -8118,7 +8118,7 @@ acl_fetch_proto_http(struct proxy *px, struct session *s, void *l7, int dir,
|
|||
}
|
||||
|
||||
/* Try to decode HTTP request */
|
||||
if (likely(req->lr < req->r))
|
||||
if (likely(req->lr < buffer_wrap_add(req, req->p + req->i)))
|
||||
http_msg_analyzer(req, msg, &txn->hdr_idx);
|
||||
|
||||
if (unlikely(msg->msg_state < HTTP_MSG_BODY)) {
|
||||
|
|
|
|||
|
|
@ -282,23 +282,22 @@ int stream_sock_read(int fd) {
|
|||
*/
|
||||
if (buffer_empty(b)) {
|
||||
/* let's realign the buffer to optimize I/O */
|
||||
b->r = b->p = b->lr = b->data;
|
||||
b->p = b->lr = b->data;
|
||||
}
|
||||
else if (b->data + b->o < b->p &&
|
||||
b->p + b->i < b->data + b->size) {
|
||||
/* remaining space wraps at the end, with a moving limit */
|
||||
if (max > b->data + b->size - b->r)
|
||||
max = b->data + b->size - b->r;
|
||||
if (max > b->data + b->size - (b->p + b->i))
|
||||
max = b->data + b->size - (b->p + b->i);
|
||||
}
|
||||
/* else max is already OK */
|
||||
|
||||
/*
|
||||
* 2. read the largest possible block
|
||||
*/
|
||||
ret = recv(fd, b->r, max, 0);
|
||||
ret = recv(fd, buffer_wrap_add(b, b->p + b->i), max, 0);
|
||||
|
||||
if (ret > 0) {
|
||||
b->r += ret;
|
||||
b->i += ret;
|
||||
cur_read += ret;
|
||||
|
||||
|
|
@ -320,11 +319,6 @@ int stream_sock_read(int fd) {
|
|||
fdtab[fd].state = FD_STREADY;
|
||||
|
||||
b->flags |= BF_READ_PARTIAL;
|
||||
|
||||
if (b->r == b->data + b->size) {
|
||||
b->r = b->data; /* wrap around the buffer */
|
||||
}
|
||||
|
||||
b->total += ret;
|
||||
|
||||
if (buffer_len(b) >= buffer_max_len(b)) {
|
||||
|
|
@ -653,7 +647,7 @@ static int stream_sock_write_loop(struct stream_interface *si, struct buffer *b)
|
|||
b->o -= ret;
|
||||
if (likely(!buffer_len(b)))
|
||||
/* optimize data alignment in the buffer */
|
||||
b->r = b->p = b->lr = b->data;
|
||||
b->lr = b->p = b->data;
|
||||
|
||||
if (likely(buffer_len(b) < buffer_max_len(b)))
|
||||
b->flags &= ~BF_FULL;
|
||||
|
|
|
|||
Loading…
Reference in a new issue