]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: proto_htx: Add functions htx_perform_server_redirect
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 24 Oct 2018 19:18:04 +0000 (21:18 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 18 Nov 2018 21:08:58 +0000 (22:08 +0100)
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
src/proto_http.c
src/proto_htx.c

index 40e82b2c361faa05d07dd0cf4c7a62eb331ffc77..0d3d7df059a720169901b46d8bf1bae2d24f77a7 100644 (file)
@@ -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);
 
index fc46826b5c4148ce6c662f0b61c50c5aa11c69f0..90d1b859c70ef08e17f5c4d561be9bc5caec6329 100644 (file)
@@ -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);
index d7dbabac9c6c494e45bd4cad25cd18f6b8b95636..391470f004b19fbde0c546a049e2c665a9a06976 100644 (file)
@@ -31,6 +31,7 @@
 #include <proto/pattern.h>
 #include <proto/proto_http.h>
 #include <proto/proxy.h>
+#include <proto/server.h>
 #include <proto/stream.h>
 #include <proto/stream_interface.h>
 #include <proto/stats.h>
@@ -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.
  */