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 7112f88..8cebc70 100644
--- a/include/haproxy/http_client-t.h
+++ b/include/haproxy/http_client-t.h
@@ -27,7 +27,7 @@
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 1d99aa7..96ec092 100644
--- a/include/haproxy/http_client.h
+++ b/include/haproxy/http_client.h
@@ -8,6 +8,7 @@
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 c8576e7..6df1226 100644
--- a/src/http_client.c
+++ b/src/http_client.c
@@ -404,6 +404,34 @@
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 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 @@
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 @@
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 @@
}
ha_free(&hc->res.hdrs);
b_free(&hc->res.buf);
-
+ sockaddr_free(&hc->dst);
free(hc);