]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: httpclient: sets an alternative destination
authorWilliam Lallemand <wlallemand@haproxy.org>
Thu, 17 Feb 2022 18:10:55 +0000 (19:10 +0100)
committerWilliam Lallemand <wlallemand@haproxy.org>
Thu, 17 Feb 2022 19:07:00 +0000 (20:07 +0100)
httpclient_set_dst() allows to set an alternative destination address
using HAProxy addres format. This will ignore the address within the
URL.

include/haproxy/http_client-t.h
include/haproxy/http_client.h
src/http_client.c

index 7112f88e5811f81ab2bf652ab35add9514333acc..8cebc70a32fa2a592a6a1ae7d88fb73b79df531b 100644 (file)
@@ -27,7 +27,7 @@ struct httpclient {
                void (*res_payload)(struct httpclient *hc);         /* payload received */
                void (*res_end)(struct httpclient *hc);             /* end of the response */
        } ops;
-       struct sockaddr_storage dst;          /* destination address */
+       struct sockaddr_storage *dst;         /* destination address */
        struct appctx *appctx;                /* HTTPclient appctx */
        void *caller;                         /* ptr of the caller */
        unsigned int flags;                   /* other flags */
index 1d99aa7d17ed0a418c5ba6f1180958b7ed66ab2b..96ec09294fc4b99331b6a65dae849538da00fdfc 100644 (file)
@@ -8,6 +8,7 @@ void httpclient_stop_and_destroy(struct httpclient *hc);
 struct httpclient *httpclient_new(void *caller, enum http_meth_t meth, struct ist url);
 
 struct appctx *httpclient_start(struct httpclient *hc);
+int httpclient_set_dst(struct httpclient *hc, const char *dst);
 int httpclient_res_xfer(struct httpclient *hc, struct buffer *dst);
 int httpclient_req_gen(struct httpclient *hc, const struct ist url, enum http_meth_t meth, const struct http_hdr *hdrs, const struct ist payload);
 int httpclient_req_xfer(struct httpclient *hc, struct ist src, int end);
index c8576e7645eb03747c790916e47e8f3ca7a96627..6df1226c8acf28765ec66d9e7c1056ca06fd394e 100644 (file)
@@ -404,6 +404,34 @@ error:
        return ret;
 }
 
+/*
+ * Sets a destination for the httpclient from an HAProxy addr format
+ * This will prevent to determine the destination from the URL
+ * Return 0 in case of success or -1 otherwise.
+ */
+int httpclient_set_dst(struct httpclient *hc, const char *dst)
+{
+       struct sockaddr_storage *sk;
+       char *errmsg = NULL;
+
+       sockaddr_free(&hc->dst);
+       /* 'sk' is statically allocated (no need to be freed). */
+       sk = str2sa_range(dst, NULL, NULL, NULL, NULL, NULL,
+                         &errmsg, NULL, NULL,
+                         PA_O_PORT_OK | PA_O_STREAM | PA_O_XPRT | PA_O_CONNECT);
+       if (!sk) {
+               ha_alert("httpclient: Failed to parse destination address in %s\n", errmsg);
+               free(errmsg);
+               return -1;
+       }
+
+       if (!sockaddr_alloc(&hc->dst, sk, sizeof(*sk))) {
+               ha_alert("httpclient: Failed to allocate sockaddr in %s:%d.\n", __FUNCTION__, __LINE__);
+               return -1;
+       }
+
+       return 0;
+}
 
 /*
  * Start the HTTP client
@@ -421,6 +449,8 @@ struct appctx *httpclient_start(struct httpclient *hc)
        struct session *sess;
        struct stream *s;
        int len;
+       struct sockaddr_storage ss_url;
+       struct sockaddr_storage* ss_dst;
        struct split_url out;
 
        /* if the client was started and not ended, an applet is already
@@ -431,8 +461,7 @@ struct appctx *httpclient_start(struct httpclient *hc)
        hc->flags = 0;
 
        /* parse URI and fill sockaddr_storage */
-       /* FIXME: use a resolver */
-       len = url2sa(istptr(hc->req.url), istlen(hc->req.url), &hc->dst, &out);
+       len = url2sa(istptr(hc->req.url), istlen(hc->req.url), &ss_url, &out);
        if (len == -1) {
                ha_alert("httpclient: cannot parse uri '%s'.\n", istptr(hc->req.url));
                goto out;
@@ -454,7 +483,13 @@ struct appctx *httpclient_start(struct httpclient *hc)
                goto out_free_appctx;
        }
 
-       if (!sockaddr_alloc(&s->si[1].dst, &hc->dst, sizeof(hc->dst))) {
+       /* if httpclient_set_dst() was used, sets the alternative address */
+       if (hc->dst)
+               ss_dst = hc->dst;
+       else
+               ss_dst = &ss_url;
+
+       if (!sockaddr_alloc(&s->si[1].dst, ss_dst, sizeof(*hc->dst))) {
                ha_alert("httpclient: Failed to initialize stream in %s:%d.\n", __FUNCTION__, __LINE__);
                goto out_free_stream;
        }
@@ -553,7 +588,7 @@ void httpclient_destroy(struct httpclient *hc)
        }
        ha_free(&hc->res.hdrs);
        b_free(&hc->res.buf);
-
+       sockaddr_free(&hc->dst);
 
        free(hc);