From: William Lallemand Date: Thu, 17 Feb 2022 18:10:55 +0000 (+0100) Subject: MINOR: httpclient: sets an alternative destination X-Git-Tag: v2.6-dev2~114 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7b2e0ee1c1d40fbf6bb95f103e61d4a1cb24aaf5;p=thirdparty%2Fhaproxy.git MINOR: httpclient: sets an alternative destination httpclient_set_dst() allows to set an alternative destination address using HAProxy addres format. This will ignore the address within the URL. --- diff --git a/include/haproxy/http_client-t.h b/include/haproxy/http_client-t.h index 7112f88e58..8cebc70a32 100644 --- a/include/haproxy/http_client-t.h +++ b/include/haproxy/http_client-t.h @@ -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 */ diff --git a/include/haproxy/http_client.h b/include/haproxy/http_client.h index 1d99aa7d17..96ec09294f 100644 --- a/include/haproxy/http_client.h +++ b/include/haproxy/http_client.h @@ -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); diff --git a/src/http_client.c b/src/http_client.c index c8576e7645..6df1226c8a 100644 --- a/src/http_client.c +++ b/src/http_client.c @@ -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);