From: Willy Tarreau Date: Thu, 17 Apr 2014 18:18:08 +0000 (+0200) Subject: MEDIUM: http: add a small helper to compute how far to rewind to find headers X-Git-Tag: v1.5-dev23~26 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=211cdece7963c956d2f9447f9ae1eddd96fc497d;p=thirdparty%2Fhaproxy.git MEDIUM: http: add a small helper to compute how far to rewind to find headers http_hdr_rewind() returns the number of bytes to rewind before buf->p to find the beginning of headers. At the moment it's not exact as it still relies on buf->o, assuming that no other data from a past message were pending there, but it's what was done till there. The purpose is to centralize further ->sov changes aiming at avoiding to rely on buf->o. --- diff --git a/include/proto/proto_http.h b/include/proto/proto_http.h index c49cb4ef3c..6566c0a565 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 e40b560825..5a011b1513 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 1334579cb5..0c30d0e018 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);