diff --git a/include/proto/proto_http.h b/include/proto/proto_http.h index c49cb4ef3..6566c0a56 100644 --- a/include/proto/proto_http.h +++ b/include/proto/proto_http.h @@ -131,6 +131,15 @@ enum http_meth_t find_http_meth(const char *str, const int len); } while (0) +/* Return the amount of bytes that need to be rewound before buf->p to access + * the current message's headers. The purpose is to be able to easily fetch + * the message's beginning before headers are forwarded, as well as after. + */ +static inline int http_hdr_rewind(const struct http_msg *msg) +{ + return msg->chn->buf->o; +} + /* Return the maximum amount of bytes that may be read after the beginning of * the message body, according to the advertised length. The function is safe * for use between HTTP_MSG_BODY and HTTP_MSG_DATA regardless of whether the diff --git a/src/backend.c b/src/backend.c index e40b56082..5a011b151 100644 --- a/src/backend.c +++ b/src/backend.c @@ -299,7 +299,7 @@ struct server *get_server_ph_post(struct session *s) struct proxy *px = s->be; unsigned int plen = px->url_param_len; unsigned long len = http_body_bytes(msg); - const char *params = b_ptr(req->buf, (int)(msg->sov + msg->sol - req->buf->o)); + const char *params = b_ptr(req->buf, (int)(msg->sov + msg->sol - http_hdr_rewind(msg))); const char *p = params; const char *start, *end; @@ -386,7 +386,7 @@ struct server *get_server_hh(struct session *s) ctx.idx = 0; /* if the message is chunked, we skip the chunk size, but use the value as len */ - http_find_header2(px->hh_name, plen, b_ptr(s->req->buf, (int)-s->req->buf->o), &txn->hdr_idx, &ctx); + http_find_header2(px->hh_name, plen, b_ptr(s->req->buf, -http_hdr_rewind(&txn->req)), &txn->hdr_idx, &ctx); /* if the header is not found or empty, let's fallback to round robin */ if (!ctx.idx || !ctx.vlen) @@ -615,7 +615,7 @@ int assign_server(struct session *s) if (s->txn.req.msg_state < HTTP_MSG_BODY) break; srv = get_server_uh(s->be, - b_ptr(s->req->buf, (int)(s->txn.req.sl.rq.u - s->req->buf->o)), + b_ptr(s->req->buf, (int)(s->txn.req.sl.rq.u - http_hdr_rewind(&s->txn.req))), s->txn.req.sl.rq.u_l); break; @@ -625,7 +625,7 @@ int assign_server(struct session *s) break; srv = get_server_ph(s->be, - b_ptr(s->req->buf, (int)(s->txn.req.sl.rq.u - s->req->buf->o)), + b_ptr(s->req->buf, (int)(s->txn.req.sl.rq.u - http_hdr_rewind(&s->txn.req))), s->txn.req.sl.rq.u_l); if (!srv && s->txn.meth == HTTP_METH_POST) @@ -967,7 +967,7 @@ static void assign_tproxy_address(struct session *s) ((struct sockaddr_in *)&srv_conn->addr.from)->sin_port = 0; ((struct sockaddr_in *)&srv_conn->addr.from)->sin_addr.s_addr = 0; - b_rew(s->req->buf, rewind = s->req->buf->o); + b_rew(s->req->buf, rewind = http_hdr_rewind(&s->txn.req)); if (http_get_hdr(&s->txn.req, src->bind_hdr_name, src->bind_hdr_len, &s->txn.hdr_idx, src->bind_hdr_occ, NULL, &vptr, &vlen)) { ((struct sockaddr_in *)&srv_conn->addr.from)->sin_addr.s_addr = diff --git a/src/proto_http.c b/src/proto_http.c index 1334579cb..0c30d0e01 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -948,7 +948,7 @@ void http_perform_server_redirect(struct session *s, struct stream_interface *si * to temporarily rewind the buffer. */ txn = &s->txn; - b_rew(s->req->buf, rewind = s->req->buf->o); + b_rew(s->req->buf, rewind = http_hdr_rewind(&txn->req)); path = http_get_path(txn); len = buffer_count(s->req->buf, path, b_ptr(s->req->buf, txn->req.sl.rq.u + txn->req.sl.rq.u_l)); @@ -4441,7 +4441,7 @@ int http_send_name_header(struct http_txn *txn, struct proxy* be, const char* sr ctx.idx = 0; - old_o = chn->buf->o; + old_o = http_hdr_rewind(&txn->req); if (old_o) { /* The request was already skipped, let's restore it */ b_rew(chn->buf, old_o);