MINOR: proto_htx: Send valid HTX message when redir mode is enabled on a server

The function htx_perform_server_redirect() has been rewritten to send a valid
HTX message.
This commit is contained in:
Christopher Faulet 2018-11-28 17:46:40 +01:00 committed by Willy Tarreau
parent 12c51e28dd
commit 0eaed6bb08

View File

@ -4899,17 +4899,21 @@ static int htx_handle_stats(struct stream *s, struct channel *req)
void htx_perform_server_redirect(struct stream *s, struct stream_interface *si)
{
struct http_txn *txn = s->txn;
struct channel *req = &s->req;
struct channel *res = &s->res;
struct server *srv;
struct htx *htx;
struct htx_sl *sl;
struct server *srv;
struct ist path;
struct ist path, location;
unsigned int flags;
size_t data;
/* 1: create the response header */
if (!chunk_memcat(&trash, HTTP_302, strlen(HTTP_302)))
return;
/*
* Create the location
*/
chunk_reset(&trash);
/* 2: add the server's prefix */
/* 1: add the server's prefix */
/* special prefix "/" means don't change URL */
srv = __objt_server(s->target);
if (srv->rdr_len != 1 || *srv->rdr_pfx != '/') {
@ -4917,8 +4921,8 @@ void htx_perform_server_redirect(struct stream *s, struct stream_interface *si)
return;
}
/* 3: add the request Path */
htx = htx_from_buf(&s->req.buf);
/* 2: add the request Path */
htx = htx_from_buf(&req->buf);
sl = http_find_stline(htx);
path = http_get_path(htx_sl_req_uri(sl));
if (!path.ptr)
@ -4926,29 +4930,64 @@ void htx_perform_server_redirect(struct stream *s, struct stream_interface *si)
if (!chunk_memcat(&trash, path.ptr, path.len))
return;
location = ist2(trash.area, trash.data);
if (unlikely(txn->flags & TX_USE_PX_CONN)) {
if (!chunk_memcat(&trash, "\r\nProxy-Connection: close\r\n\r\n", 29))
return;
}
else {
if (!chunk_memcat(&trash, "\r\nConnection: close\r\n\r\n", 23))
return;
}
/*
* Create the 302 respone
*/
htx = htx_from_buf(&res->buf);
flags = (HTX_SL_F_IS_RESP|HTX_SL_F_VER_11|HTX_SL_F_XFER_LEN|HTX_SL_F_BODYLESS);
sl = htx_add_stline(htx, HTX_BLK_RES_SL, flags,
ist("HTTP/1.1"), ist("302"), ist("Found"));
if (!sl)
goto fail;
sl->info.res.status = 302;
s->txn->status = 302;
/* prepare to return without error. */
if (!htx_add_header(htx, ist("Cache-Control"), ist("no-cache")) ||
!htx_add_header(htx, ist("Connection"), ist("close")) ||
!htx_add_header(htx, ist("Content-length"), ist("0")) ||
!htx_add_header(htx, ist("Location"), location))
goto fail;
if (!htx_add_endof(htx, HTX_BLK_EOH) || !htx_add_endof(htx, HTX_BLK_EOM))
goto fail;
/*
* Send the message
*/
data = htx->data - co_data(res);
b_set_data(&res->buf, b_size(&res->buf));
c_adv(res, data);
res->total += data;
/* return without error. */
si_shutr(si);
si_shutw(si);
si->err_type = SI_ET_NONE;
si->state = SI_ST_CLO;
/* send the message */
txn->status = 302;
htx_server_error(s, si, SF_ERR_LOCAL, SF_FINST_C, &trash);
channel_auto_read(req);
channel_abort(req);
channel_auto_close(req);
channel_erase(req);
channel_auto_read(res);
channel_auto_close(res);
if (!(s->flags & SF_ERR_MASK))
s->flags |= SF_ERR_LOCAL;
if (!(s->flags & SF_FINST_MASK))
s->flags |= SF_FINST_C;
/* FIXME: we should increase a counter of redirects per server and per backend. */
srv_inc_sess_ctr(srv);
srv_set_sess_last(srv);
return;
fail:
/* If an error occurred, remove the incomplete HTTP response from the
* buffer */
channel_truncate(res);
}
/* This function terminates the request because it was completly analyzed or