From cde18fc1bac432c7625c702c5a3150692cfa5c90 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Wed, 30 May 2012 07:59:54 +0200 Subject: [PATCH] BUG/MINOR: perform_http_redirect also needs to rewind the buffer Commit d1de8af362905d43bcd96e7522fcee62a93a53bf was incomplete, because perform_http_redirect() also needs to rewind the buffer since it's called after data are scheduled for forwarding. No backport needed. --- src/proto_http.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/proto_http.c b/src/proto_http.c index b41b70a5b..45860164a 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -754,6 +754,8 @@ http_get_path(struct http_txn *txn) /* Returns a 302 for a redirectable request. This may only be called just after * the stream interface has moved to SI_ST_ASS. Unprocessable requests are * left unchanged and will follow normal proxy processing. + * NOTE: this function is designed to support being called once data are scheduled + * for forwarding. */ void perform_http_redirect(struct session *s, struct stream_interface *si) { @@ -761,7 +763,7 @@ void perform_http_redirect(struct session *s, struct stream_interface *si) struct chunk rdr; struct server *srv; char *path; - int len; + int len, rewind; /* 1: create the response header */ rdr.len = strlen(HTTP_302); @@ -781,13 +783,20 @@ void perform_http_redirect(struct session *s, struct stream_interface *si) rdr.len += srv->rdr_len; } - /* 3: add the request URI */ + /* 3: add the request URI. Since it was already forwarded, we need + * to temporarily rewind the buffer. + */ txn = &s->txn; + b_rew(s->req, rewind = s->req->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)); + + b_adv(s->req, rewind); + if (!path) return; - len = txn->req.sl.rq.u_l + (s->req->p + txn->req.sl.rq.u) - path; if (rdr.len + len > rdr.size - 4) /* 4 for CRLF-CRLF */ return;