From fefc73da3458aff351ac17c934f8fcd77d0337ef Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Wed, 24 Oct 2018 21:18:04 +0200 Subject: [PATCH] MINOR: proto_htx: Add functions htx_perform_server_redirect It is more or less the same than legacy version but adapted to be called from HTX analyzers. In the legacy version of this function, we switch on the HTX code when applicable. --- include/proto/proto_http.h | 1 + src/proto_http.c | 3 +++ src/proto_htx.c | 55 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) diff --git a/include/proto/proto_http.h b/include/proto/proto_http.h index 40e82b2c3..0d3d7df05 100644 --- a/include/proto/proto_http.h +++ b/include/proto/proto_http.h @@ -75,6 +75,7 @@ void htx_res_set_status(unsigned int status, const char *reason, struct stream * void htx_check_request_for_cacheability(struct stream *s, struct channel *req); void htx_check_response_for_cacheability(struct stream *s, struct channel *res); int htx_send_name_header(struct stream *s, struct proxy *be, const char *srv_name); +void htx_perform_server_redirect(struct stream *s, struct stream_interface *si); void htx_server_error(struct stream *s, struct stream_interface *si, int err, int finst, const struct buffer *msg); void htx_reply_and_close(struct stream *s, short status, struct buffer *msg); diff --git a/src/proto_http.c b/src/proto_http.c index fc46826b5..90d1b859c 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -467,6 +467,9 @@ void http_perform_server_redirect(struct stream *s, struct stream_interface *si) char *path; int len, rewind; + if (IS_HTX_STRM(s)) + return htx_perform_server_redirect(s, si); + /* 1: create the response header */ trash.data = strlen(HTTP_302); memcpy(trash.area, HTTP_302, trash.data); diff --git a/src/proto_htx.c b/src/proto_htx.c index d7dbabac9..391470f00 100644 --- a/src/proto_htx.c +++ b/src/proto_htx.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -4765,6 +4766,60 @@ int htx_send_name_header(struct stream *s, struct proxy *be, const char *srv_nam return 0; } +void htx_perform_server_redirect(struct stream *s, struct stream_interface *si) +{ + struct http_txn *txn = s->txn; + struct htx *htx; + struct server *srv; + union h1_sl sl; + struct ist path; + + /* 1: create the response header */ + if (!chunk_memcat(&trash, HTTP_302, strlen(HTTP_302))) + return; + + /* 2: 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 != '/') { + if (!chunk_memcat(&trash, srv->rdr_pfx, srv->rdr_len)) + return; + } + + /* 3: add the request Path */ + htx = htx_from_buf(&s->req.buf); + sl = http_find_stline(htx); + path = http_get_path(sl.rq.u); + if (!path.ptr) + return; + + if (!chunk_memcat(&trash, path.ptr, path.len)) + return; + + 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; + } + + /* prepare to 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); + + /* FIXME: we should increase a counter of redirects per server and per backend. */ + srv_inc_sess_ctr(srv); + srv_set_sess_last(srv); +} + /* This function terminates the request because it was completly analyzed or * because an error was triggered during the body forwarding. */