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.
This commit is contained in:
Willy Tarreau 2012-05-30 07:59:54 +02:00
parent a32d275ab0
commit cde18fc1ba

View File

@ -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 /* 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 * the stream interface has moved to SI_ST_ASS. Unprocessable requests are
* left unchanged and will follow normal proxy processing. * 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) 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 chunk rdr;
struct server *srv; struct server *srv;
char *path; char *path;
int len; int len, rewind;
/* 1: create the response header */ /* 1: create the response header */
rdr.len = strlen(HTTP_302); 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; 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; txn = &s->txn;
b_rew(s->req, rewind = s->req->o);
path = http_get_path(txn); 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) if (!path)
return; 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 */ if (rdr.len + len > rdr.size - 4) /* 4 for CRLF-CRLF */
return; return;