int bo_getblk(struct channel *buf, char *blk, int len, int offset);
int buffer_replace2(struct channel *b, char *pos, char *end, const char *str, int len);
int buffer_insert_line2(struct channel *b, char *pos, const char *str, int len);
-void buffer_dump(FILE *o, struct channel *b, int from, int to);
-void buffer_slow_realign(struct channel *buf);
-void buffer_bounce_realign(struct channel *buf);
+void buffer_dump(FILE *o, struct buffer *b, int from, int to);
+void buffer_slow_realign(struct buffer *buf);
+void buffer_bounce_realign(struct buffer *buf);
unsigned long long buffer_forward(struct channel *buf, unsigned long long bytes);
/* Initialize all fields in the buffer. The BF_OUT_EMPTY flags is set. */
static inline void buffer_init(struct channel *buf)
{
- buf->o = 0;
- buf->i = 0;
+ buf->buf.o = 0;
+ buf->buf.i = 0;
+ buf->buf.p = buf->buf.data;
buf->to_forward = 0;
buf->total = 0;
buf->pipe = NULL;
buf->analysers = 0;
buf->cons = NULL;
buf->flags = BF_OUT_EMPTY;
- buf->p = buf->data;
}
/*****************************************************************/
})
/* Returns the start of the input data in a buffer */
-static inline char *bi_ptr(const struct channel *b)
+static inline char *bi_ptr(const struct buffer *b)
{
return b->p;
}
/* Returns the end of the input data in a buffer (pointer to next
* insertion point).
*/
-static inline char *bi_end(const struct channel *b)
+static inline char *bi_end(const struct buffer *b)
{
char *ret = b->p + b->i;
}
/* Returns the amount of input data that can contiguously be read at once */
-static inline int bi_contig_data(const struct channel *b)
+static inline int bi_contig_data(const struct buffer *b)
{
int data = b->data + b->size - b->p;
}
/* Returns the start of the output data in a buffer */
-static inline char *bo_ptr(const struct channel *b)
+static inline char *bo_ptr(const struct buffer *b)
{
char *ret = b->p - b->o;
}
/* Returns the end of the output data in a buffer */
-static inline char *bo_end(const struct channel *b)
+static inline char *bo_end(const struct buffer *b)
{
return b->p;
}
/* Returns the amount of output data that can contiguously be read at once */
-static inline int bo_contig_data(const struct channel *b)
+static inline int bo_contig_data(const struct buffer *b)
{
char *beg = b->p - b->o;
}
/* Return the buffer's length in bytes by summing the input and the output */
-static inline int buffer_len(const struct channel *buf)
+static inline int buffer_len(const struct buffer *buf)
{
return buf->i + buf->o;
}
/* Return non-zero only if the buffer is not empty */
-static inline int buffer_not_empty(const struct channel *buf)
+static inline int buffer_not_empty(const struct buffer *buf)
{
return buf->i | buf->o;
}
/* Return non-zero only if the buffer is empty */
-static inline int buffer_empty(const struct channel *buf)
+static inline int buffer_empty(const struct buffer *buf)
{
return !buffer_not_empty(buf);
}
/* Normalizes a pointer after a subtract */
-static inline char *buffer_wrap_sub(const struct channel *buf, char *ptr)
+static inline char *buffer_wrap_sub(const struct buffer *buf, char *ptr)
{
if (ptr < buf->data)
ptr += buf->size;
}
/* Normalizes a pointer after an addition */
-static inline char *buffer_wrap_add(const struct channel *buf, char *ptr)
+static inline char *buffer_wrap_add(const struct buffer *buf, char *ptr)
{
if (ptr - buf->size >= buf->data)
ptr -= buf->size;
*/
static inline int buffer_reserved(const struct channel *buf)
{
- int ret = global.tune.maxrewrite - buf->to_forward - buf->o;
+ int ret = global.tune.maxrewrite - buf->to_forward - buf->buf.o;
if (buf->to_forward == BUF_INFINITE_FORWARD)
return 0;
*/
static inline int buffer_max_len(const struct channel *buf)
{
- return buf->size - buffer_reserved(buf);
+ return buf->buf.size - buffer_reserved(buf);
}
/* Returns non-zero if the buffer input is considered full. The reserved space
*/
static inline int bi_full(const struct channel *b)
{
- int rem = b->size;
+ int rem = b->buf.size;
- rem -= b->o;
- rem -= b->i;
+ rem -= b->buf.o;
+ rem -= b->buf.i;
if (!rem)
return 1; /* buffer already full */
- if (b->to_forward >= b->size ||
- (BUF_INFINITE_FORWARD < MAX_RANGE(typeof(b->size)) && // just there to ensure gcc
+ if (b->to_forward >= b->buf.size ||
+ (BUF_INFINITE_FORWARD < MAX_RANGE(typeof(b->buf.size)) && // just there to ensure gcc
b->to_forward == BUF_INFINITE_FORWARD)) // avoids the useless second
return 0; // test whenever possible
rem -= global.tune.maxrewrite;
- rem += b->o;
+ rem += b->buf.o;
rem += b->to_forward;
return rem <= 0;
}
*/
static inline int bi_avail(const struct channel *b)
{
- int rem = b->size;
+ int rem = b->buf.size;
int rem2;
- rem -= b->o;
- rem -= b->i;
+ rem -= b->buf.o;
+ rem -= b->buf.i;
if (!rem)
return rem; /* buffer already full */
- if (b->to_forward >= b->size ||
- (BUF_INFINITE_FORWARD < MAX_RANGE(typeof(b->size)) && // just there to ensure gcc
+ if (b->to_forward >= b->buf.size ||
+ (BUF_INFINITE_FORWARD < MAX_RANGE(typeof(b->buf.size)) && // just there to ensure gcc
b->to_forward == BUF_INFINITE_FORWARD)) // avoids the useless second
return rem; // test whenever possible
rem2 = rem - global.tune.maxrewrite;
- rem2 += b->o;
+ rem2 += b->buf.o;
rem2 += b->to_forward;
if (rem > rem2)
/* Return the maximum amount of bytes that can be written into the buffer,
* including reserved space which may be overwritten.
*/
-static inline int buffer_total_space(const struct channel *buf)
+static inline int buffer_total_space(const struct buffer *buf)
{
return buf->size - buffer_len(buf);
}
* and enforces a limit on buf->data + buf->size. <start> must be within the
* buffer.
*/
-static inline int buffer_contig_area(const struct channel *buf, const char *start, int count)
+static inline int buffer_contig_area(const struct buffer *buf, const char *start, int count)
{
if (count > buf->data - start + buf->size)
count = buf->data - start + buf->size;
/* Return the amount of bytes that can be written into the buffer at once,
* including reserved space which may be overwritten.
*/
-static inline int buffer_contig_space(const struct channel *buf)
+static inline int buffer_contig_space(const struct buffer *buf)
{
const char *left, *right;
*/
static inline void b_adv(struct channel *b, unsigned int adv)
{
- b->i -= adv;
- b->o += adv;
- if (b->o)
+ b->buf.i -= adv;
+ b->buf.o += adv;
+ if (b->buf.o)
b->flags &= ~BF_OUT_EMPTY;
- b->p = b_ptr(b, adv);
+ b->buf.p = b_ptr(&b->buf, adv);
}
/* Rewinds the buffer by <adv> bytes, which means that the buffer pointer goes
*/
static inline void b_rew(struct channel *b, unsigned int adv)
{
- b->i += adv;
- b->o -= adv;
- if (!b->o && !b->pipe)
+ b->buf.i += adv;
+ b->buf.o -= adv;
+ if (!b->buf.o && !b->pipe)
b->flags |= BF_OUT_EMPTY;
- b->p = b_ptr(b, (int)-adv);
+ b->buf.p = b_ptr(&b->buf, (int)-adv);
}
/* Return the amount of bytes that can be written into the buffer at once,
* excluding the amount of reserved space passed in <res>, which is
* preserved.
*/
-static inline int buffer_contig_space_with_res(const struct channel *buf, int res)
+static inline int buffer_contig_space_with_res(const struct buffer *buf, int res)
{
/* Proceed differently if the buffer is full, partially used or empty.
* The hard situation is when it's partially used and either data or
/* 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 channel *buf)
+static inline int buffer_contig_space_res(const struct channel *chn)
{
- return buffer_contig_space_with_res(buf, buffer_reserved(buf));
+ return buffer_contig_space_with_res(&chn->buf, buffer_reserved(chn));
}
/* Normalizes a pointer which is supposed to be relative to the beginning of a
* once, so the original pointer must be between ->data-size and ->data+2*size-1,
* otherwise an invalid pointer might be returned.
*/
-static inline const char *buffer_pointer(const struct channel *buf, const char *ptr)
+static inline const char *buffer_pointer(const struct buffer *buf, const char *ptr)
{
if (ptr < buf->data)
ptr += buf->size;
/* Returns the distance between two pointers, taking into account the ability
* to wrap around the buffer's end.
*/
-static inline int buffer_count(const struct channel *buf, const char *from, const char *to)
+static inline int buffer_count(const struct buffer *buf, const char *from, const char *to)
{
int count = to - from;
if (count < 0)
/* returns the amount of pending bytes in the buffer. It is the amount of bytes
* that is not scheduled to be sent.
*/
-static inline int buffer_pending(const struct channel *buf)
+static inline int buffer_pending(const struct buffer *buf)
{
return buf->i;
}
* <end>. It always starts at buf->p. The work area includes the
* reserved area.
*/
-static inline int buffer_work_area(const struct channel *buf, const char *end)
+static inline int buffer_work_area(const struct buffer *buf, const char *end)
{
end = buffer_pointer(buf, end);
if (end == buffer_wrap_add(buf, buf->p + buf->i))
}
/* Return 1 if the buffer has less than 1/4 of its capacity free, otherwise 0 */
-static inline int buffer_almost_full(const struct channel *buf)
+static inline int buffer_almost_full(const struct buffer *buf)
{
if (buffer_total_space(buf) < buf->size / 4)
return 1;
*/
static inline void buffer_flush(struct channel *buf)
{
- buf->p = buffer_wrap_add(buf, buf->p + buf->i);
- buf->o += buf->i;
- buf->i = 0;
- if (buf->o)
+ buf->buf.p = buffer_wrap_add(&buf->buf, buf->buf.p + buf->buf.i);
+ buf->buf.o += buf->buf.i;
+ buf->buf.i = 0;
+ if (buf->buf.o)
buf->flags &= ~BF_OUT_EMPTY;
}
*/
static inline void buffer_erase(struct channel *buf)
{
- buf->o = 0;
- buf->i = 0;
+ buf->buf.o = 0;
+ buf->buf.i = 0;
buf->to_forward = 0;
- buf->p = buf->data;
+ buf->buf.p = buf->buf.data;
buf->flags &= ~(BF_FULL | BF_OUT_EMPTY);
if (!buf->pipe)
buf->flags |= BF_OUT_EMPTY;
*/
static inline void bi_erase(struct channel *buf)
{
- if (!buf->o)
+ if (!buf->buf.o)
return buffer_erase(buf);
buf->to_forward = 0;
- if (!buf->i)
+ if (!buf->buf.i)
return;
- buf->i = 0;
+ buf->buf.i = 0;
buf->flags &= ~BF_FULL;
if (bi_full(buf))
buf->flags |= BF_FULL;
* This is mainly used to remove empty lines at the beginning of a request
* or a response.
*/
-static inline void bi_fast_delete(struct channel *buf, int n)
+static inline void bi_fast_delete(struct buffer *buf, int n)
{
buf->i -= n;
buf->p += n;
* Tries to realign the given buffer, and returns how many bytes can be written
* there at once without overwriting anything.
*/
-static inline int buffer_realign(struct channel *buf)
+static inline int buffer_realign(struct buffer *buf)
{
if (!(buf->i | buf->o)) {
/* let's realign the buffer to optimize I/O */
*/
static inline void bo_skip(struct channel *buf, int len)
{
- buf->o -= len;
- if (!buf->o && !buf->pipe)
+ buf->buf.o -= len;
+ if (!buf->buf.o && !buf->pipe)
buf->flags |= BF_OUT_EMPTY;
- if (buffer_len(buf) == 0)
- buf->p = buf->data;
+ if (buffer_len(&buf->buf) == 0)
+ buf->buf.p = buf->buf.data;
if (!bi_full(buf))
buf->flags &= ~BF_FULL;
return -2;
return -1;
}
- return *buffer_wrap_sub(buf, buf->p - buf->o);
+ return *buffer_wrap_sub(&buf->buf, buf->buf.p - buf->buf.o);
}
/* This function writes the string <str> at position <pos> which must be in
"[%04d] req: p=%d(%d) s=%d bf=%08x an=%08x data=%p size=%d l=%d w=%p r=%p o=%p sm=%d fw=%ld tf=%08x\n",
line,
s->si[0].state, s->si[0].fd, s->txn.req.msg_state, s->req->flags, s->req->analysers,
- s->req->data, s->req->size, s->req->l, s->req->w, s->req->r, s->req->p, s->req->o, s->req->to_forward, s->txn.flags);
+ s->req->buf.data, s->req->buf.size, s->req->l, s->req->w, s->req->r, s->req->buf.p, s->req->buf.o, s->req->to_forward, s->txn.flags);
write(-1, trash, size);
size = 0;
size += snprintf(trash + size, trashlen - size,
" %04d rep: p=%d(%d) s=%d bf=%08x an=%08x data=%p size=%d l=%d w=%p r=%p o=%p sm=%d fw=%ld\n",
line,
s->si[1].state, s->si[1].fd, s->txn.rsp.msg_state, s->rep->flags, s->rep->analysers,
- s->rep->data, s->rep->size, s->rep->l, s->rep->w, s->rep->r, s->rep->p, s->rep->o, s->rep->to_forward);
+ s->rep->buf.data, s->rep->buf.size, s->rep->l, s->rep->w, s->rep->r, s->rep->buf.p, s->rep->buf.o, s->rep->to_forward);
write(-1, trash, size);
}
int bytes, len;
len = strlen(text);
- bytes = buffer_insert_line2(msg->buf, msg->buf->p + msg->eoh, text, len);
+ bytes = buffer_insert_line2(msg->buf, msg->buf->buf.p + msg->eoh, text, len);
if (!bytes)
return -1;
http_msg_move_end(msg, bytes);
{
int bytes;
- bytes = buffer_insert_line2(msg->buf, msg->buf->p + msg->eoh, text, len);
+ bytes = buffer_insert_line2(msg->buf, msg->buf->buf.p + msg->eoh, text, len);
if (!bytes)
return -1;
http_msg_move_end(msg, bytes);
{
char *ptr, *end;
- ptr = txn->req.buf->p + txn->req.sl.rq.u;
+ ptr = txn->req.buf->buf.p + txn->req.sl.rq.u;
end = ptr + txn->req.sl.rq.u_l;
if (ptr >= end)
* to temporarily rewind the buffer.
*/
txn = &s->txn;
- b_rew(s->req, rewind = s->req->o);
+ b_rew(s->req, rewind = s->req->buf.o);
path = http_get_path(txn);
- len = buffer_count(s->req, path, b_ptr(s->req, txn->req.sl.rq.u + txn->req.sl.rq.u_l));
+ len = buffer_count(&s->req->buf, path, b_ptr(&s->req->buf, txn->req.sl.rq.u + txn->req.sl.rq.u_l));
b_adv(s->req, rewind);
unsigned int state, const char *ptr, const char *end,
unsigned int *ret_ptr, unsigned int *ret_state)
{
- const char *msg_start = msg->buf->p;
+ const char *msg_start = msg->buf->buf.p;
switch (state) {
case HTTP_MSG_RPVER:
unsigned int state, const char *ptr, const char *end,
unsigned int *ret_ptr, unsigned int *ret_state)
{
- const char *msg_start = msg->buf->p;
+ const char *msg_start = msg->buf->buf.p;
switch (state) {
case HTTP_MSG_RQMETH:
len = strlen(h);
}
- if (!http_find_header2(h, len, s->req->p, &txn->hdr_idx, &ctx))
+ if (!http_find_header2(h, len, s->req->buf.p, &txn->hdr_idx, &ctx))
return 0;
h = ctx.line + ctx.val;
struct channel *buf = msg->buf;
state = msg->msg_state;
- ptr = buf->p + msg->next;
- end = buf->p + buf->i;
+ ptr = buf->buf.p + msg->next;
+ end = buf->buf.p + buf->buf.i;
if (unlikely(ptr >= end))
goto http_msg_ood;
* first if we need to remove some CRLF. We can only
* do this when o=0.
*/
- if (unlikely(ptr != buf->p)) {
- if (buf->o)
+ if (unlikely(ptr != buf->buf.p)) {
+ if (buf->buf.o)
goto http_msg_ood;
/* Remove empty leading lines, as recommended by RFC2616. */
- bi_fast_delete(buf, ptr - buf->p);
+ bi_fast_delete(&buf->buf, ptr - buf->buf.p);
}
msg->sol = 0;
hdr_idx_init(idx);
*/
hdr_idx_set_start(idx, msg->sl.st.l, *ptr == '\r');
- msg->sol = ptr - buf->p;
+ msg->sol = ptr - buf->buf.p;
if (likely(*ptr == '\r'))
EAT_AND_JUMP_OR_RETURN(http_msg_rpline_end, HTTP_MSG_RPLINE_END);
goto http_msg_rpline_end;
* first if we need to remove some CRLF. We can only
* do this when o=0.
*/
- if (likely(ptr != buf->p)) {
- if (buf->o)
+ if (likely(ptr != buf->buf.p)) {
+ if (buf->buf.o)
goto http_msg_ood;
/* Remove empty leading lines, as recommended by RFC2616. */
- bi_fast_delete(buf, ptr - buf->p);
+ bi_fast_delete(&buf->buf, ptr - buf->buf.p);
}
msg->sol = 0;
/* we will need this when keep-alive will be supported
*/
hdr_idx_set_start(idx, msg->sl.rq.l, *ptr == '\r');
- msg->sol = ptr - buf->p;
+ msg->sol = ptr - buf->buf.p;
if (likely(*ptr == '\r'))
EAT_AND_JUMP_OR_RETURN(http_msg_rqline_end, HTTP_MSG_RQLINE_END);
goto http_msg_rqline_end;
*/
case HTTP_MSG_HDR_FIRST:
http_msg_hdr_first:
- msg->sol = ptr - buf->p;
+ msg->sol = ptr - buf->buf.p;
if (likely(!HTTP_IS_CRLF(*ptr))) {
goto http_msg_hdr_name;
}
goto http_msg_invalid;
if (msg->err_pos == -1) /* capture error pointer */
- msg->err_pos = ptr - buf->p; /* >= 0 now */
+ msg->err_pos = ptr - buf->buf.p; /* >= 0 now */
/* and we still accept this non-token character */
EAT_AND_JUMP_OR_RETURN(http_msg_hdr_name, HTTP_MSG_HDR_NAME);
EAT_AND_JUMP_OR_RETURN(http_msg_hdr_l1_sp, HTTP_MSG_HDR_L1_SP);
/* header value can be basically anything except CR/LF */
- msg->sov = ptr - buf->p;
+ msg->sov = ptr - buf->buf.p;
if (likely(!HTTP_IS_CRLF(*ptr))) {
goto http_msg_hdr_val;
http_msg_hdr_l1_lws:
if (likely(HTTP_IS_SPHT(*ptr))) {
/* replace HT,CR,LF with spaces */
- for (; buf->p + msg->sov < ptr; msg->sov++)
- buf->p[msg->sov] = ' ';
+ for (; buf->buf.p + msg->sov < ptr; msg->sov++)
+ buf->buf.p[msg->sov] = ' ';
goto http_msg_hdr_l1_sp;
}
/* we had a header consisting only in spaces ! */
if (likely(!HTTP_IS_CRLF(*ptr)))
EAT_AND_JUMP_OR_RETURN(http_msg_hdr_val, HTTP_MSG_HDR_VAL);
- msg->eol = ptr - buf->p;
+ msg->eol = ptr - buf->buf.p;
/* Note: we could also copy eol into ->eoh so that we have the
* real header end in case it ends with lots of LWS, but is this
* really needed ?
http_msg_hdr_l2_lws:
if (unlikely(HTTP_IS_SPHT(*ptr))) {
/* LWS: replace HT,CR,LF with spaces */
- for (; buf->p + msg->eol < ptr; msg->eol++)
- buf->p[msg->eol] = ' ';
+ for (; buf->buf.p + msg->eol < ptr; msg->eol++)
+ buf->buf.p[msg->eol] = ' ';
goto http_msg_hdr_val;
}
http_msg_complete_header:
* first CR or LF so we know how the line ends. We insert last
* header into the index.
*/
- if (unlikely(hdr_idx_add(msg->eol - msg->sol, buf->p[msg->eol] == '\r',
+ if (unlikely(hdr_idx_add(msg->eol - msg->sol, buf->buf.p[msg->eol] == '\r',
idx, idx->tail) < 0))
goto http_msg_invalid;
- msg->sol = ptr - buf->p;
+ msg->sol = ptr - buf->buf.p;
if (likely(!HTTP_IS_CRLF(*ptr))) {
goto http_msg_hdr_name;
}
/* Assumes msg->sol points to the first of either CR or LF */
EXPECT_LF_HERE(ptr, http_msg_invalid);
ptr++;
- msg->sov = msg->next = ptr - buf->p;
+ msg->sov = msg->next = ptr - buf->buf.p;
msg->eoh = msg->sol;
msg->sol = 0;
msg->msg_state = HTTP_MSG_BODY;
http_msg_ood:
/* out of data */
msg->msg_state = state;
- msg->next = ptr - buf->p;
+ msg->next = ptr - buf->buf.p;
return;
http_msg_invalid:
/* invalid message */
msg->msg_state = HTTP_MSG_ERROR;
- msg->next = ptr - buf->p;
+ msg->next = ptr - buf->buf.p;
return;
}
if (msg->sl.rq.v_l != 0)
return 1;
- cur_end = msg->buf->p + msg->sl.rq.l;
+ cur_end = msg->buf->buf.p + msg->sl.rq.l;
delta = 0;
if (msg->sl.rq.u_l == 0) {
cur_end += delta;
cur_end = (char *)http_parse_reqline(msg,
HTTP_MSG_RQMETH,
- msg->buf->p, cur_end + 1,
+ msg->buf->buf.p, cur_end + 1,
NULL, NULL);
if (unlikely(!cur_end))
return 0;
ctx.idx = 0;
txn->flags &= ~(TX_CON_KAL_SET|TX_CON_CLO_SET);
- while (http_find_header2(hdr_val, hdr_len, msg->buf->p, &txn->hdr_idx, &ctx)) {
+ while (http_find_header2(hdr_val, hdr_len, msg->buf->buf.p, &txn->hdr_idx, &ctx)) {
if (ctx.vlen >= 10 && word_match(ctx.line + ctx.val, ctx.vlen, "keep-alive", 10)) {
txn->flags |= TX_HDR_CONN_KAL;
if (to_del & 2)
}
txn->flags &= ~(TX_CON_CLO_SET | TX_CON_KAL_SET);
- while (http_find_header2(hdr_val, hdr_len, msg->buf->p, &txn->hdr_idx, &ctx)) {
+ while (http_find_header2(hdr_val, hdr_len, msg->buf->buf.p, &txn->hdr_idx, &ctx)) {
if (ctx.vlen >= 10 && word_match(ctx.line + ctx.val, ctx.vlen, "keep-alive", 10)) {
if (wanted & TX_CON_KAL_SET)
txn->flags |= TX_CON_KAL_SET;
int http_parse_chunk_size(struct http_msg *msg)
{
const struct channel *buf = msg->buf;
- const char *ptr = b_ptr(buf, msg->next);
+ const char *ptr = b_ptr(&buf->buf, msg->next);
const char *ptr_old = ptr;
- const char *end = buf->data + buf->size;
- const char *stop = bi_end(buf);
+ const char *end = buf->buf.data + buf->buf.size;
+ const char *stop = bi_end(&buf->buf);
unsigned int chunk = 0;
/* The chunk size is in the following form, though we are only
if (c < 0) /* not a hex digit anymore */
break;
if (++ptr >= end)
- ptr = buf->data;
+ ptr = buf->buf.data;
if (chunk & 0xF8000000) /* integer overflow will occur if result >= 2GB */
goto error;
chunk = (chunk << 4) + c;
while (http_is_spht[(unsigned char)*ptr]) {
if (++ptr >= end)
- ptr = buf->data;
+ ptr = buf->buf.data;
if (ptr == stop)
return 0;
}
/* we now have a CR or an LF at ptr */
if (likely(*ptr == '\r')) {
if (++ptr >= end)
- ptr = buf->data;
+ ptr = buf->buf.data;
if (ptr == stop)
return 0;
}
if (*ptr != '\n')
goto error;
if (++ptr >= end)
- ptr = buf->data;
+ ptr = buf->buf.data;
/* done */
break;
}
else if (*ptr == ';') {
/* chunk extension, ends at next CRLF */
if (++ptr >= end)
- ptr = buf->data;
+ ptr = buf->buf.data;
if (ptr == stop)
return 0;
while (!HTTP_IS_CRLF(*ptr)) {
if (++ptr >= end)
- ptr = buf->data;
+ ptr = buf->buf.data;
if (ptr == stop)
return 0;
}
* ->sov.
*/
msg->sov += ptr - ptr_old;
- msg->next = buffer_count(buf, buf->p, ptr);
+ msg->next = buffer_count(&buf->buf, buf->buf.p, ptr);
msg->chunk_len = chunk;
msg->body_len += chunk;
msg->msg_state = chunk ? HTTP_MSG_DATA : HTTP_MSG_TRAILERS;
return 1;
error:
- msg->err_pos = buffer_count(buf, buf->p, ptr);
+ msg->err_pos = buffer_count(&buf->buf, buf->buf.p, ptr);
return -1;
}
/* we have msg->next which points to next line. Look for CRLF. */
while (1) {
const char *p1 = NULL, *p2 = NULL;
- const char *ptr = b_ptr(buf, msg->next);
- const char *stop = bi_end(buf);
+ const char *ptr = b_ptr(&buf->buf, msg->next);
+ const char *stop = bi_end(&buf->buf);
int bytes;
/* scan current line and stop at LF or CRLF */
if (*ptr == '\r') {
if (p1) {
- msg->err_pos = buffer_count(buf, buf->p, ptr);
+ msg->err_pos = buffer_count(&buf->buf, buf->buf.p, ptr);
return -1;
}
p1 = ptr;
}
ptr++;
- if (ptr >= buf->data + buf->size)
- ptr = buf->data;
+ if (ptr >= buf->buf.data + buf->buf.size)
+ ptr = buf->buf.data;
}
/* after LF; point to beginning of next line */
p2++;
- if (p2 >= buf->data + buf->size)
- p2 = buf->data;
+ if (p2 >= buf->buf.data + buf->buf.size)
+ p2 = buf->buf.data;
- bytes = p2 - b_ptr(buf, msg->next);
+ bytes = p2 - b_ptr(&buf->buf, msg->next);
if (bytes < 0)
- bytes += buf->size;
+ bytes += buf->buf.size;
/* schedule this line for forwarding */
msg->sov += bytes;
- if (msg->sov >= buf->size)
- msg->sov -= buf->size;
+ if (msg->sov >= buf->buf.size)
+ msg->sov -= buf->buf.size;
- if (p1 == b_ptr(buf, msg->next)) {
+ if (p1 == b_ptr(&buf->buf, msg->next)) {
/* LF/CRLF at beginning of line => end of trailers at p2.
* Everything was scheduled for forwarding, there's nothing
* left from this message.
*/
- msg->next = buffer_count(buf, buf->p, p2);
+ msg->next = buffer_count(&buf->buf, buf->buf.p, p2);
msg->msg_state = HTTP_MSG_DONE;
return 1;
}
/* OK, next line then */
- msg->next = buffer_count(buf, buf->p, p2);
+ msg->next = buffer_count(&buf->buf, buf->buf.p, p2);
}
}
* against the correct length.
*/
bytes = 1;
- ptr = buf->p;
+ ptr = buf->buf.p;
if (*ptr == '\r') {
bytes++;
ptr++;
- if (ptr >= buf->data + buf->size)
- ptr = buf->data;
+ if (ptr >= buf->buf.data + buf->buf.size)
+ ptr = buf->buf.data;
}
- if (bytes > buf->i)
+ if (bytes > buf->buf.i)
return 0;
if (*ptr != '\n') {
- msg->err_pos = buffer_count(buf, buf->p, ptr);
+ msg->err_pos = buffer_count(&buf->buf, buf->buf.p, ptr);
return -1;
}
ptr++;
- if (ptr >= buf->data + buf->size)
- ptr = buf->data;
+ if (ptr >= buf->buf.data + buf->buf.size)
+ ptr = buf->buf.data;
/* prepare the CRLF to be forwarded (between ->sol and ->sov) */
msg->sol = 0;
msg->sov = msg->next = bytes;
* For the parsing, we use a 28 states FSM.
*
* Here is the information we currently have :
- * req->p = beginning of request
- * req->p + msg->eoh = end of processed headers / start of current one
- * req->p + req->i = end of input data
+ * req->buf.p = beginning of request
+ * req->buf.p + msg->eoh = end of processed headers / start of current one
+ * req->buf.p + req->buf.i = end of input data
* msg->eol = end of current header or line (LF or CRLF)
* msg->next = first non-visited byte
*
req,
req->rex, req->wex,
req->flags,
- req->i,
+ req->buf.i,
req->analysers);
/* we're speaking HTTP here, so let's speak HTTP to the client */
* protected area is affected, because we may have to move processed
* data later, which is much more complicated.
*/
- if (buffer_not_empty(req) && msg->msg_state < HTTP_MSG_ERROR) {
+ if (buffer_not_empty(&req->buf) && msg->msg_state < HTTP_MSG_ERROR) {
if ((txn->flags & TX_NOT_FIRST) &&
unlikely((req->flags & BF_FULL) ||
- bi_end(req) < b_ptr(req, msg->next) ||
- bi_end(req) > req->data + req->size - global.tune.maxrewrite)) {
- if (req->o) {
+ bi_end(&req->buf) < b_ptr(&req->buf, msg->next) ||
+ bi_end(&req->buf) > req->buf.data + req->buf.size - global.tune.maxrewrite)) {
+ if (req->buf.o) {
if (req->flags & (BF_SHUTW|BF_SHUTW_NOW|BF_WRITE_ERROR|BF_WRITE_TIMEOUT))
goto failed_keep_alive;
/* some data has still not left the buffer, wake us once that's done */
req->flags |= BF_READ_DONTWAIT; /* try to get back here ASAP */
return 0;
}
- if (bi_end(req) < b_ptr(req, msg->next) ||
- bi_end(req) > req->data + req->size - global.tune.maxrewrite)
- buffer_slow_realign(msg->buf);
+ if (bi_end(&req->buf) < b_ptr(&req->buf, msg->next) ||
+ bi_end(&req->buf) > req->buf.data + req->buf.size - global.tune.maxrewrite)
+ buffer_slow_realign(&msg->buf->buf);
}
/* Note that we have the same problem with the response ; we
*/
if ((txn->flags & TX_NOT_FIRST) &&
unlikely((s->rep->flags & BF_FULL) ||
- bi_end(s->rep) < b_ptr(s->rep, txn->rsp.next) ||
- bi_end(s->rep) > s->rep->data + s->rep->size - global.tune.maxrewrite)) {
- if (s->rep->o) {
+ bi_end(&s->rep->buf) < b_ptr(&s->rep->buf, txn->rsp.next) ||
+ bi_end(&s->rep->buf) > s->rep->buf.data + s->rep->buf.size - global.tune.maxrewrite)) {
+ if (s->rep->buf.o) {
if (s->rep->flags & (BF_SHUTW|BF_SHUTW_NOW|BF_WRITE_ERROR|BF_WRITE_TIMEOUT))
goto failed_keep_alive;
/* don't let a connection request be initiated */
}
}
- if (likely(msg->next < req->i)) /* some unparsed data are available */
+ if (likely(msg->next < req->buf.i)) /* some unparsed data are available */
http_msg_analyzer(msg, &txn->hdr_idx);
}
(msg->msg_state >= HTTP_MSG_BODY || msg->msg_state == HTTP_MSG_ERROR))) {
char *eol, *sol;
- sol = req->p;
+ sol = req->buf.p;
eol = sol + msg->sl.rq.l;
debug_hdr("clireq", s, sol, eol);
session_inc_http_err_ctr(s);
proxy_inc_fe_req_ctr(s->fe);
if (msg->err_pos < 0)
- msg->err_pos = req->i;
+ msg->err_pos = req->buf.i;
goto return_bad_req;
}
req->flags |= BF_READ_DONTWAIT; /* try to get back here ASAP */
s->rep->flags &= ~BF_EXPECT_MORE; /* speed up sending a previous response */
#ifdef TCP_QUICKACK
- if (s->listener->options & LI_O_NOQUICKACK && req->i) {
+ if (s->listener->options & LI_O_NOQUICKACK && req->buf.i) {
/* We need more data, we have to re-enable quick-ack in case we
* previously disabled it, otherwise we might cause the client
* to delay next data.
/* OK now we have a complete HTTP request with indexed headers. Let's
* complete the request parsing by setting a few fields we will need
- * later. At this point, we have the last CRLF at req->data + msg->eoh.
+ * later. At this point, we have the last CRLF at req->buf.data + msg->eoh.
* If the request is in HTTP/0.9 form, the rule is still true, and eoh
* points to the CRLF of the request line. msg->next points to the first
* byte after the last LF. msg->sov points to the first byte of data.
/*
* 1: identify the method
*/
- txn->meth = find_http_meth(req->p, msg->sl.rq.m_l);
+ txn->meth = find_http_meth(req->buf.p, msg->sl.rq.m_l);
/* we can make use of server redirect on GET and HEAD */
if (txn->meth == HTTP_METH_GET || txn->meth == HTTP_METH_HEAD)
*/
if (unlikely((s->fe->monitor_uri_len != 0) &&
(s->fe->monitor_uri_len == msg->sl.rq.u_l) &&
- !memcmp(req->p + msg->sl.rq.u,
+ !memcmp(req->buf.p + msg->sl.rq.u,
s->fe->monitor_uri,
s->fe->monitor_uri_len))) {
/*
if (urilen >= REQURI_LEN)
urilen = REQURI_LEN - 1;
- memcpy(txn->uri, req->p, urilen);
+ memcpy(txn->uri, req->buf.p, urilen);
txn->uri[urilen] = 0;
if (!(s->logs.logwait &= ~LW_REQ))
/* ... and check if the request is HTTP/1.1 or above */
if ((msg->sl.rq.v_l == 8) &&
- ((req->p[msg->sl.rq.v + 5] > '1') ||
- ((req->p[msg->sl.rq.v + 5] == '1') &&
- (req->p[msg->sl.rq.v + 7] >= '1'))))
+ ((req->buf.p[msg->sl.rq.v + 5] > '1') ||
+ ((req->buf.p[msg->sl.rq.v + 5] == '1') &&
+ (req->buf.p[msg->sl.rq.v + 7] >= '1'))))
msg->flags |= HTTP_MSGF_VER_11;
/* "connection" has not been parsed yet */
* CONNECT ip:port.
*/
if ((s->fe->options2 & PR_O2_USE_PXHDR) &&
- req->p[msg->sl.rq.u] != '/' && req->p[msg->sl.rq.u] != '*')
+ req->buf.p[msg->sl.rq.u] != '/' && req->buf.p[msg->sl.rq.u] != '*')
txn->flags |= TX_USE_PX_CONN;
/* transfer length unknown*/
/* 5: we may need to capture headers */
if (unlikely((s->logs.logwait & LW_REQHDR) && txn->req.cap))
- capture_headers(req->p, &txn->hdr_idx,
+ capture_headers(req->buf.p, &txn->hdr_idx,
txn->req.cap, s->fe->req_cap);
/* 6: determine the transfer-length.
ctx.idx = 0;
/* set TE_CHNK and XFER_LEN only if "chunked" is seen last */
while ((msg->flags & HTTP_MSGF_VER_11) &&
- http_find_header2("Transfer-Encoding", 17, req->p, &txn->hdr_idx, &ctx)) {
+ http_find_header2("Transfer-Encoding", 17, req->buf.p, &txn->hdr_idx, &ctx)) {
if (ctx.vlen == 7 && strncasecmp(ctx.line + ctx.val, "chunked", 7) == 0)
msg->flags |= (HTTP_MSGF_TE_CHNK | HTTP_MSGF_XFER_LEN);
else if (msg->flags & HTTP_MSGF_TE_CHNK) {
ctx.idx = 0;
while (!(msg->flags & HTTP_MSGF_TE_CHNK) && !use_close_only &&
- http_find_header2("Content-Length", 14, req->p, &txn->hdr_idx, &ctx)) {
+ http_find_header2("Content-Length", 14, req->buf.p, &txn->hdr_idx, &ctx)) {
signed long long cl;
if (!ctx.vlen) {
- msg->err_pos = ctx.line + ctx.val - req->p;
+ msg->err_pos = ctx.line + ctx.val - req->buf.p;
goto return_bad_req;
}
if (strl2llrc(ctx.line + ctx.val, ctx.vlen, &cl)) {
- msg->err_pos = ctx.line + ctx.val - req->p;
+ msg->err_pos = ctx.line + ctx.val - req->buf.p;
goto return_bad_req; /* parse failure */
}
if (cl < 0) {
- msg->err_pos = ctx.line + ctx.val - req->p;
+ msg->err_pos = ctx.line + ctx.val - req->buf.p;
goto return_bad_req;
}
if ((msg->flags & HTTP_MSGF_CNT_LEN) && (msg->chunk_len != cl)) {
- msg->err_pos = ctx.line + ctx.val - req->p;
+ msg->err_pos = ctx.line + ctx.val - req->buf.p;
goto return_bad_req; /* already specified, was different */
}
char *st_cur_param = NULL;
char *st_next_param = NULL;
- first_param = req->p + txn->req.eoh + 2;
+ first_param = req->buf.p + txn->req.eoh + 2;
end_params = first_param + txn->req.body_len;
cur_param = next_param = end_params;
- if (end_params >= req->data + req->size - global.tune.maxrewrite) {
+ if (end_params >= req->buf.data + req->buf.size - global.tune.maxrewrite) {
/* Prevent buffer overflow */
si->applet.ctx.stats.st_code = STAT_STATUS_EXCD;
return 1;
}
- else if (end_params > req->p + req->i) {
+ else if (end_params > req->buf.p + req->buf.i) {
/* we need more data */
si->applet.ctx.stats.st_code = STAT_STATUS_NONE;
return 0;
req,
req->rex, req->wex,
req->flags,
- req->i,
+ req->buf.i,
req->analysers);
/* first check whether we have some ACLs set to block this request */
struct hdr_ctx ctx;
ctx.idx = 0;
/* Expect is allowed in 1.1, look for it */
- if (http_find_header2("Expect", 6, req->p, &txn->hdr_idx, &ctx) &&
+ if (http_find_header2("Expect", 6, req->buf.p, &txn->hdr_idx, &ctx) &&
unlikely(ctx.vlen == 12 && strncasecmp(ctx.line+ctx.val, "100-continue", 12) == 0)) {
bo_inject(s->rep, http_100_chunk.str, http_100_chunk.len);
}
path = http_get_path(txn);
/* build message using path */
if (path) {
- pathlen = txn->req.sl.rq.u_l + (req->p + txn->req.sl.rq.u) - path;
+ pathlen = txn->req.sl.rq.u_l + (req->buf.p + txn->req.sl.rq.u) - path;
if (rule->flags & REDIRECT_FLAG_DROP_QS) {
int qs = 0;
while (qs < pathlen) {
rdr.len += 4;
bo_inject(req->prod->ob, rdr.str, rdr.len);
/* "eat" the request */
- bi_fast_delete(req, msg->sov);
+ bi_fast_delete(&req->buf, msg->sov);
msg->sov = 0;
req->analysers = AN_REQ_HTTP_XFER_BODY;
s->rep->analysers = AN_RES_HTTP_XFER_BODY;
req,
req->rex, req->wex,
req->flags,
- req->i,
+ req->buf.i,
req->analysers);
/*
* parsing incoming request.
*/
if ((s->be->options & PR_O_HTTP_PROXY) && !(s->flags & SN_ADDR_SET)) {
- url2sa(req->p + msg->sl.rq.u, msg->sl.rq.u_l, &s->req->cons->addr.to);
+ url2sa(req->buf.p + msg->sl.rq.u, msg->sl.rq.u_l, &s->req->cons->addr.to);
}
/*
/* It needs to look into the URI unless persistence must be ignored */
if ((txn->sessid == NULL) && s->be->appsession_name && !(s->flags & SN_IGNORE_PRST)) {
- get_srv_from_appsession(s, req->p + msg->sl.rq.u, msg->sl.rq.u_l);
+ get_srv_from_appsession(s, req->buf.p + msg->sl.rq.u, msg->sl.rq.u_l);
}
/* add unique-id if "header-unique-id" is specified */
if (!((s->fe->options | s->be->options) & PR_O_FF_ALWAYS) &&
http_find_header2(s->be->fwdfor_hdr_len ? s->be->fwdfor_hdr_name : s->fe->fwdfor_hdr_name,
s->be->fwdfor_hdr_len ? s->be->fwdfor_hdr_len : s->fe->fwdfor_hdr_len,
- req->p, &txn->hdr_idx, &ctx)) {
+ req->buf.p, &txn->hdr_idx, &ctx)) {
/* The header is set to be added only if none is present
* and we found it, so don't do anything.
*/
*/
if ((s->listener->options & LI_O_NOQUICKACK) &&
((msg->flags & HTTP_MSGF_TE_CHNK) ||
- (msg->body_len > req->i - txn->req.eoh - 2)))
+ (msg->body_len > req->buf.i - txn->req.eoh - 2)))
setsockopt(si_fd(&s->si[0]), IPPROTO_TCP, TCP_QUICKACK, &one, sizeof(one));
#endif
}
struct hdr_ctx ctx;
ctx.idx = 0;
/* Expect is allowed in 1.1, look for it */
- if (http_find_header2("Expect", 6, req->p, &txn->hdr_idx, &ctx) &&
+ if (http_find_header2("Expect", 6, req->buf.p, &txn->hdr_idx, &ctx) &&
unlikely(ctx.vlen == 12 && strncasecmp(ctx.line+ctx.val, "100-continue", 12) == 0)) {
bo_inject(s->rep, http_100_chunk.str, http_100_chunk.len);
}
if (msg->msg_state < HTTP_MSG_CHUNK_SIZE) {
/* we have msg->sov which points to the first byte of message body.
- * req->p still points to the beginning of the message and msg->sol
+ * req->buf.p still points to the beginning of the message and msg->sol
* is still null. We must save the body in msg->next because it
* survives buffer re-alignments.
*/
if (msg->body_len < limit)
limit = msg->body_len;
- if (req->i - msg->sov >= limit) /* we have enough bytes now */
+ if (req->buf.i - msg->sov >= limit) /* we have enough bytes now */
goto http_end;
missing_data:
ctx.idx = 0;
- old_o = req->o;
+ old_o = req->buf.o;
if (old_o) {
/* The request was already skipped, let's restore it */
b_rew(req, old_o);
}
- old_i = req->i;
- while (http_find_header2(hdr_name, hdr_name_len, txn->req.buf->p, &txn->hdr_idx, &ctx)) {
+ old_i = req->buf.i;
+ while (http_find_header2(hdr_name, hdr_name_len, txn->req.buf->buf.p, &txn->hdr_idx, &ctx)) {
/* remove any existing values from the header */
http_remove_header2(&txn->req, &txn->hdr_idx, &ctx);
}
* data to be forwarded in order to take into account the size
* variations.
*/
- b_adv(req, old_o + req->i - old_i);
+ b_adv(req, old_o + req->buf.i - old_i);
}
return 0;
}
/* don't count other requests' data */
- s->logs.bytes_in -= s->req->i;
- s->logs.bytes_out -= s->rep->i;
+ s->logs.bytes_in -= s->req->buf.i;
+ s->logs.bytes_out -= s->rep->buf.i;
/* let's do a final log if we need it */
if (s->logs.logwait &&
s->logs.prx_queue_size = 0; /* we get the number of pending conns before us */
s->logs.srv_queue_size = 0; /* we will get this number soon */
- s->logs.bytes_in = s->req->total = s->req->i;
- s->logs.bytes_out = s->rep->total = s->rep->i;
+ s->logs.bytes_in = s->req->total = s->req->buf.i;
+ s->logs.bytes_out = s->rep->total = s->rep->buf.i;
if (s->pend_pos)
pendconn_free(s->pend_pos);
* because the request will wait for it to flush a little
* bit before proceeding.
*/
- if (s->req->i) {
- if (s->rep->o &&
+ if (s->req->buf.i) {
+ if (s->rep->buf.o &&
!(s->rep->flags & BF_FULL) &&
- bi_end(s->rep) <= s->rep->data + s->rep->size - global.tune.maxrewrite)
+ bi_end(&s->rep->buf) <= s->rep->buf.data + s->rep->buf.size - global.tune.maxrewrite)
s->rep->flags |= BF_EXPECT_MORE;
}
return 0;
if ((req->flags & (BF_READ_ERROR|BF_READ_TIMEOUT|BF_WRITE_ERROR|BF_WRITE_TIMEOUT)) ||
- ((req->flags & BF_SHUTW) && (req->to_forward || req->o))) {
+ ((req->flags & BF_SHUTW) && (req->to_forward || req->buf.o))) {
/* Output closed while we were sending data. We must abort and
* wake the other side up.
*/
if (msg->msg_state < HTTP_MSG_CHUNK_SIZE) {
/* we have msg->sov which points to the first byte of message body.
- * req->p still points to the beginning of the message and msg->sol
+ * req->buf.p still points to the beginning of the message and msg->sol
* is still null. We must save the body in msg->next because it
* survives buffer re-alignments.
*/
rep,
rep->rex, rep->wex,
rep->flags,
- rep->i,
+ rep->buf.i,
rep->analysers);
/*
* For the parsing, we use a 28 states FSM.
*
* Here is the information we currently have :
- * rep->p = beginning of response
- * rep->p + msg->eoh = end of processed headers / start of current one
- * rep->p + rep->i = end of input data
+ * rep->buf.p = beginning of response
+ * rep->buf.p + msg->eoh = end of processed headers / start of current one
+ * rep->buf.p + rep->buf.i = end of input data
* msg->eol = end of current header or line (LF or CRLF)
* msg->next = first non-visited byte
*/
* protected area is affected, because we may have to move processed
* data later, which is much more complicated.
*/
- if (buffer_not_empty(rep) && msg->msg_state < HTTP_MSG_ERROR) {
+ if (buffer_not_empty(&rep->buf) && msg->msg_state < HTTP_MSG_ERROR) {
if (unlikely((rep->flags & BF_FULL) ||
- bi_end(rep) < b_ptr(rep, msg->next) ||
- bi_end(rep) > rep->data + rep->size - global.tune.maxrewrite)) {
- if (rep->o) {
+ bi_end(&rep->buf) < b_ptr(&rep->buf, msg->next) ||
+ bi_end(&rep->buf) > rep->buf.data + rep->buf.size - global.tune.maxrewrite)) {
+ if (rep->buf.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))
goto abort_response;
rep->flags |= BF_READ_DONTWAIT; /* try to get back here ASAP */
return 0;
}
- if (rep->i <= rep->size - global.tune.maxrewrite)
- buffer_slow_realign(msg->buf);
+ if (rep->buf.i <= rep->buf.size - global.tune.maxrewrite)
+ buffer_slow_realign(&msg->buf->buf);
}
- if (likely(msg->next < rep->i))
+ if (likely(msg->next < rep->buf.i))
http_msg_analyzer(msg, &txn->hdr_idx);
}
(msg->msg_state >= HTTP_MSG_BODY || msg->msg_state == HTTP_MSG_ERROR))) {
char *eol, *sol;
- sol = rep->p;
+ sol = rep->buf.p;
eol = sol + msg->sl.st.l;
debug_hdr("srvrep", s, sol, eol);
/* too large response does not fit in buffer. */
else if (rep->flags & BF_FULL) {
if (msg->err_pos < 0)
- msg->err_pos = rep->i;
+ msg->err_pos = rep->buf.i;
goto hdr_response_bad;
}
/*
* 1: get the status code
*/
- n = rep->p[msg->sl.st.c] - '0';
+ n = rep->buf.p[msg->sl.st.c] - '0';
if (n < 1 || n > 5)
n = 0;
/* when the client triggers a 4xx from the server, it's most often due
/* check if the response is HTTP/1.1 or above */
if ((msg->sl.st.v_l == 8) &&
- ((rep->p[5] > '1') ||
- ((rep->p[5] == '1') && (rep->p[7] >= '1'))))
+ ((rep->buf.p[5] > '1') ||
+ ((rep->buf.p[5] == '1') && (rep->buf.p[7] >= '1'))))
msg->flags |= HTTP_MSGF_VER_11;
/* "connection" has not been parsed yet */
/* transfer length unknown*/
msg->flags &= ~HTTP_MSGF_XFER_LEN;
- txn->status = strl2ui(rep->p + msg->sl.st.c, msg->sl.st.c_l);
+ txn->status = strl2ui(rep->buf.p + msg->sl.st.c, msg->sl.st.c_l);
/* Adjust server's health based on status code. Note: status codes 501
* and 505 are triggered on demand by client request, so we must not
*/
s->logs.logwait &= ~LW_RESP;
if (unlikely((s->logs.logwait & LW_RSPHDR) && txn->rsp.cap))
- capture_headers(rep->p, &txn->hdr_idx,
+ capture_headers(rep->buf.p, &txn->hdr_idx,
txn->rsp.cap, s->fe->rsp_cap);
/* 4: determine the transfer-length.
use_close_only = 0;
ctx.idx = 0;
while ((msg->flags & HTTP_MSGF_VER_11) &&
- http_find_header2("Transfer-Encoding", 17, rep->p, &txn->hdr_idx, &ctx)) {
+ http_find_header2("Transfer-Encoding", 17, rep->buf.p, &txn->hdr_idx, &ctx)) {
if (ctx.vlen == 7 && strncasecmp(ctx.line + ctx.val, "chunked", 7) == 0)
msg->flags |= (HTTP_MSGF_TE_CHNK | HTTP_MSGF_XFER_LEN);
else if (msg->flags & HTTP_MSGF_TE_CHNK) {
/* FIXME: below we should remove the content-length header(s) in case of chunked encoding */
ctx.idx = 0;
while (!(msg->flags & HTTP_MSGF_TE_CHNK) && !use_close_only &&
- http_find_header2("Content-Length", 14, rep->p, &txn->hdr_idx, &ctx)) {
+ http_find_header2("Content-Length", 14, rep->buf.p, &txn->hdr_idx, &ctx)) {
signed long long cl;
if (!ctx.vlen) {
- msg->err_pos = ctx.line + ctx.val - rep->p;
+ msg->err_pos = ctx.line + ctx.val - rep->buf.p;
goto hdr_response_bad;
}
if (strl2llrc(ctx.line + ctx.val, ctx.vlen, &cl)) {
- msg->err_pos = ctx.line + ctx.val - rep->p;
+ msg->err_pos = ctx.line + ctx.val - rep->buf.p;
goto hdr_response_bad; /* parse failure */
}
if (cl < 0) {
- msg->err_pos = ctx.line + ctx.val - rep->p;
+ msg->err_pos = ctx.line + ctx.val - rep->buf.p;
goto hdr_response_bad;
}
if ((msg->flags & HTTP_MSGF_CNT_LEN) && (msg->chunk_len != cl)) {
- msg->err_pos = ctx.line + ctx.val - rep->p;
+ msg->err_pos = ctx.line + ctx.val - rep->buf.p;
goto hdr_response_bad; /* already specified, was different */
}
rep,
rep->rex, rep->wex,
rep->flags,
- rep->i,
+ rep->buf.i,
rep->analysers);
if (unlikely(msg->msg_state < HTTP_MSG_BODY)) /* we need more data */
return 0;
if ((res->flags & (BF_READ_ERROR|BF_READ_TIMEOUT|BF_WRITE_ERROR|BF_WRITE_TIMEOUT)) ||
- ((res->flags & BF_SHUTW) && (res->to_forward || res->o)) ||
+ ((res->flags & BF_SHUTW) && (res->to_forward || res->buf.o)) ||
!s->req->analysers) {
/* Output closed while we were sending data. We must abort and
* wake the other side up.
if (msg->msg_state < HTTP_MSG_CHUNK_SIZE) {
/* we have msg->sov which points to the first byte of message body.
- * rep->p still points to the beginning of the message and msg->sol
+ * rep->buf.p still points to the beginning of the message and msg->sol
* is still null. We must save the body in msg->next because it
* survives buffer re-alignments.
*/
last_hdr = 0;
- cur_next = req->p + hdr_idx_first_pos(&txn->hdr_idx);
+ cur_next = req->buf.p + hdr_idx_first_pos(&txn->hdr_idx);
old_idx = 0;
while (!last_hdr) {
done = 0;
- cur_ptr = req->p;
+ cur_ptr = req->buf.p;
cur_end = cur_ptr + txn->req.sl.rq.l;
/* Now we have the request line between cur_ptr and cur_end */
/* Iterate through the headers, we start with the start line. */
old_idx = 0;
- hdr_next = req->p + hdr_idx_first_pos(&txn->hdr_idx);
+ hdr_next = req->buf.p + hdr_idx_first_pos(&txn->hdr_idx);
while ((cur_idx = txn->hdr_idx.v[old_idx].next)) {
struct hdr_idx_elem *cur_hdr;
last_hdr = 0;
- cur_next = rtr->p + hdr_idx_first_pos(&txn->hdr_idx);
+ cur_next = rtr->buf.p + hdr_idx_first_pos(&txn->hdr_idx);
old_idx = 0;
while (!last_hdr) {
done = 0;
- cur_ptr = rtr->p;
+ cur_ptr = rtr->buf.p;
cur_end = cur_ptr + txn->rsp.sl.st.l;
/* Now we have the status line between cur_ptr and cur_end */
/* we have a full respnse and we know that we have either a CR
* or an LF at <ptr>.
*/
- txn->status = strl2ui(rtr->p + txn->rsp.sl.st.c, txn->rsp.sl.st.c_l);
+ txn->status = strl2ui(rtr->buf.p + txn->rsp.sl.st.c, txn->rsp.sl.st.c_l);
hdr_idx_set_start(&txn->hdr_idx, txn->rsp.sl.st.l, *cur_end == '\r');
/* there is no point trying this regex on headers */
return 1;
* we start with the start line.
*/
old_idx = 0;
- hdr_next = res->p + hdr_idx_first_pos(&txn->hdr_idx);
+ hdr_next = res->buf.p + hdr_idx_first_pos(&txn->hdr_idx);
while ((cur_idx = txn->hdr_idx.v[old_idx].next)) {
struct hdr_idx_elem *cur_hdr;
* we start with the start line.
*/
cur_idx = 0;
- cur_next = rtr->p + hdr_idx_first_pos(&txn->hdr_idx);
+ cur_next = rtr->buf.p + hdr_idx_first_pos(&txn->hdr_idx);
while ((cur_idx = txn->hdr_idx.v[cur_idx].next)) {
struct hdr_idx_elem *cur_hdr;
{
struct uri_auth *uri_auth = backend->uri_auth;
struct http_msg *msg = &txn->req;
- const char *uri = msg->buf->p+ msg->sl.rq.u;
+ const char *uri = msg->buf->buf.p+ msg->sl.rq.u;
const char *h;
if (!uri_auth)
* By default it tries to report the error position as msg->err_pos. However if
* this one is not set, it will then report msg->next, which is the last known
* parsing point. The function is able to deal with wrapping buffers. It always
- * displays buffers as a contiguous area starting at buf->p.
+ * displays buffers as a contiguous area starting at buf->buf.p.
*/
void http_capture_bad_message(struct error_snapshot *es, struct session *s,
struct http_msg *msg,
struct channel *buf = msg->buf;
int len1, len2;
- es->len = MIN(buf->i, sizeof(es->buf));
- len1 = buf->data + buf->size - buf->p;
+ es->len = MIN(buf->buf.i, sizeof(es->buf));
+ len1 = buf->buf.data + buf->buf.size - buf->buf.p;
len1 = MIN(len1, es->len);
len2 = es->len - len1; /* remaining data if buffer wraps */
- memcpy(es->buf, buf->p, len1);
+ memcpy(es->buf, buf->buf.p, len1);
if (len2)
- memcpy(es->buf + len1, buf->data, len2);
+ memcpy(es->buf + len1, buf->buf.data, len2);
if (msg->err_pos >= 0)
es->pos = msg->err_pos;
es->s_flags = s->flags;
es->t_flags = s->txn.flags;
es->m_flags = msg->flags;
- es->b_out = buf->o;
- es->b_wrap = buf->data + buf->size - buf->p;
+ es->b_out = buf->buf.o;
+ es->b_wrap = buf->buf.data + buf->buf.size - buf->buf.p;
es->b_tot = buf->total;
es->m_clen = msg->chunk_len;
es->m_blen = msg->body_len;
if (occ >= 0) {
/* search from the beginning */
- while (http_find_header2(hname, hlen, msg->buf->p, idx, ctx)) {
+ while (http_find_header2(hname, hlen, msg->buf->buf.p, idx, ctx)) {
occ--;
if (occ <= 0) {
*vptr = ctx->line + ctx->val;
return 0;
found = hist_ptr = 0;
- while (http_find_header2(hname, hlen, msg->buf->p, idx, ctx)) {
+ while (http_find_header2(hname, hlen, msg->buf->buf.p, idx, ctx)) {
ptr_hist[hist_ptr] = ctx->line + ctx->val;
len_hist[hist_ptr] = ctx->vlen;
if (++hist_ptr >= MAX_HDR_HISTORY)
* a HEAD with some data, or sending more than the advertised
* content-length.
*/
- if (unlikely(s->rep->i))
- s->rep->i = 0;
+ if (unlikely(s->rep->buf.i))
+ s->rep->buf.i = 0;
s->req->rto = s->fe->timeout.client;
s->req->wto = TICK_ETERNITY;
}
/* Try to decode HTTP request */
- if (likely(msg->next < s->req->i))
+ if (likely(msg->next < s->req->buf.i))
http_msg_analyzer(msg, &txn->hdr_idx);
/* Still no valid request ? */
* preparation to perform so that further checks can rely
* on HTTP tests.
*/
- txn->meth = find_http_meth(msg->buf->p, msg->sl.rq.m_l);
+ txn->meth = find_http_meth(msg->buf->buf.p, msg->sl.rq.m_l);
if (txn->meth == HTTP_METH_GET || txn->meth == HTTP_METH_HEAD)
s->flags |= SN_REDIRECTABLE;
return 0;
smp->type = SMP_T_CSTR;
smp->data.str.len = txn->req.sl.rq.m_l;
- smp->data.str.str = txn->req.buf->p;
+ smp->data.str.str = txn->req.buf->buf.p;
}
smp->flags = SMP_F_VOL_1ST;
return 1;
CHECK_HTTP_MESSAGE_FIRST();
len = txn->req.sl.rq.v_l;
- ptr = txn->req.buf->p + txn->req.sl.rq.v;
+ ptr = txn->req.buf->buf.p + txn->req.sl.rq.v;
while ((len-- > 0) && (*ptr++ != '/'));
if (len <= 0)
CHECK_HTTP_MESSAGE_FIRST();
len = txn->rsp.sl.st.v_l;
- ptr = txn->rsp.buf->p;
+ ptr = txn->rsp.buf->buf.p;
while ((len-- > 0) && (*ptr++ != '/'));
if (len <= 0)
CHECK_HTTP_MESSAGE_FIRST();
len = txn->rsp.sl.st.c_l;
- ptr = txn->rsp.buf->p + txn->rsp.sl.st.c;
+ ptr = txn->rsp.buf->buf.p + txn->rsp.sl.st.c;
smp->type = SMP_T_UINT;
smp->data.uint = __strl2ui(ptr, len);
smp->type = SMP_T_CSTR;
smp->data.str.len = txn->req.sl.rq.u_l;
- smp->data.str.str = txn->req.buf->p + txn->req.sl.rq.u;
+ smp->data.str.str = txn->req.buf->buf.p + txn->req.sl.rq.u;
smp->flags = SMP_F_VOL_1ST;
return 1;
}
CHECK_HTTP_MESSAGE_FIRST();
/* Parse HTTP request */
- url2sa(txn->req.buf->p + txn->req.sl.rq.u, txn->req.sl.rq.u_l, &l4->req->cons->addr.to);
+ url2sa(txn->req.buf->buf.p + txn->req.sl.rq.u, txn->req.sl.rq.u_l, &l4->req->cons->addr.to);
if (((struct sockaddr_in *)&l4->req->cons->addr.to)->sin_family != AF_INET)
return 0;
smp->type = SMP_T_IPV4;
CHECK_HTTP_MESSAGE_FIRST();
/* Same optimization as url_ip */
- url2sa(txn->req.buf->p + txn->req.sl.rq.u, txn->req.sl.rq.u_l, &l4->req->cons->addr.to);
+ url2sa(txn->req.buf->buf.p + txn->req.sl.rq.u, txn->req.sl.rq.u_l, &l4->req->cons->addr.to);
smp->type = SMP_T_UINT;
smp->data.uint = ntohs(((struct sockaddr_in *)&l4->req->cons->addr.to)->sin_port);
ctx.idx = 0;
cnt = 0;
- while (http_find_header2(args->data.str.str, args->data.str.len, msg->buf->p, idx, &ctx))
+ while (http_find_header2(args->data.str.str, args->data.str.len, msg->buf->buf.p, idx, &ctx))
cnt++;
smp->type = SMP_T_UINT;
CHECK_HTTP_MESSAGE_FIRST();
- end = txn->req.buf->p + txn->req.sl.rq.u + txn->req.sl.rq.u_l;
+ end = txn->req.buf->buf.p + txn->req.sl.rq.u + txn->req.sl.rq.u_l;
ptr = http_get_path(txn);
if (!ptr)
return 0;
CHECK_HTTP_MESSAGE_FIRST();
ctx.idx = 0;
- if (!http_find_header2("Host", 4, txn->req.buf->p + txn->req.sol, &txn->hdr_idx, &ctx) ||
+ if (!http_find_header2("Host", 4, txn->req.buf->buf.p + txn->req.sol, &txn->hdr_idx, &ctx) ||
!ctx.vlen)
return smp_fetch_path(px, l4, l7, opt, args, smp);
smp->data.str.len = ctx.vlen;
/* now retrieve the path */
- end = txn->req.buf->p + txn->req.sol + txn->req.sl.rq.u + txn->req.sl.rq.u_l;
+ end = txn->req.buf->buf.p + txn->req.sol + txn->req.sl.rq.u + txn->req.sl.rq.u_l;
beg = http_get_path(txn);
if (!beg)
beg = end;
* next one.
*/
- sol = msg->buf->p;
+ sol = msg->buf->buf.p;
if (!(smp->flags & SMP_F_NOT_LAST)) {
/* search for the header from the beginning, we must first initialize
* the search parameters.
hdr_name_len = 10;
}
- sol = msg->buf->p;
+ sol = msg->buf->buf.p;
val_end = val_beg = NULL;
ctx.idx = 0;
cnt = 0;
CHECK_HTTP_MESSAGE_FIRST();
- if (!find_url_param_value(msg->buf->p + msg->sl.rq.u, msg->sl.rq.u_l,
+ if (!find_url_param_value(msg->buf->buf.p + msg->sl.rq.u, msg->sl.rq.u_l,
args->data.str.str, args->data.str.len,
&smp->data.str.str, &smp->data.str.len))
return 0;