mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-18 19:50:54 +00:00
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:
parent
12c51e28dd
commit
0eaed6bb08
@ -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)
|
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 *htx;
|
||||||
struct htx_sl *sl;
|
struct htx_sl *sl;
|
||||||
struct server *srv;
|
struct ist path, location;
|
||||||
struct ist path;
|
unsigned int flags;
|
||||||
|
size_t data;
|
||||||
|
|
||||||
/* 1: create the response header */
|
/*
|
||||||
if (!chunk_memcat(&trash, HTTP_302, strlen(HTTP_302)))
|
* Create the location
|
||||||
return;
|
*/
|
||||||
|
chunk_reset(&trash);
|
||||||
|
|
||||||
/* 2: add the server's prefix */
|
/* 1: add the server's prefix */
|
||||||
/* special prefix "/" means don't change URL */
|
/* special prefix "/" means don't change URL */
|
||||||
srv = __objt_server(s->target);
|
srv = __objt_server(s->target);
|
||||||
if (srv->rdr_len != 1 || *srv->rdr_pfx != '/') {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 3: add the request Path */
|
/* 2: add the request Path */
|
||||||
htx = htx_from_buf(&s->req.buf);
|
htx = htx_from_buf(&req->buf);
|
||||||
sl = http_find_stline(htx);
|
sl = http_find_stline(htx);
|
||||||
path = http_get_path(htx_sl_req_uri(sl));
|
path = http_get_path(htx_sl_req_uri(sl));
|
||||||
if (!path.ptr)
|
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))
|
if (!chunk_memcat(&trash, path.ptr, path.len))
|
||||||
return;
|
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))
|
* Create the 302 respone
|
||||||
return;
|
*/
|
||||||
}
|
htx = htx_from_buf(&res->buf);
|
||||||
else {
|
flags = (HTX_SL_F_IS_RESP|HTX_SL_F_VER_11|HTX_SL_F_XFER_LEN|HTX_SL_F_BODYLESS);
|
||||||
if (!chunk_memcat(&trash, "\r\nConnection: close\r\n\r\n", 23))
|
sl = htx_add_stline(htx, HTX_BLK_RES_SL, flags,
|
||||||
return;
|
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_shutr(si);
|
||||||
si_shutw(si);
|
si_shutw(si);
|
||||||
si->err_type = SI_ET_NONE;
|
si->err_type = SI_ET_NONE;
|
||||||
si->state = SI_ST_CLO;
|
si->state = SI_ST_CLO;
|
||||||
|
|
||||||
/* send the message */
|
channel_auto_read(req);
|
||||||
txn->status = 302;
|
channel_abort(req);
|
||||||
htx_server_error(s, si, SF_ERR_LOCAL, SF_FINST_C, &trash);
|
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. */
|
/* FIXME: we should increase a counter of redirects per server and per backend. */
|
||||||
srv_inc_sess_ctr(srv);
|
srv_inc_sess_ctr(srv);
|
||||||
srv_set_sess_last(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
|
/* This function terminates the request because it was completly analyzed or
|
||||||
|
Loading…
Reference in New Issue
Block a user