mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-18 11:47:03 +00:00
MEDIUM: httpclient: allow to use another proxy
httpclient_new_from_proxy() is a variant of httpclient_new() which allows to create the requests from a different proxy. The proxy and its 2 servers are now stored in the httpclient structure. The proxy must have been created with httpclient_create_proxy() to be used. The httpclient_postcheck() callback will finish the initialization of all proxies created with PR_CAP_HTTPCLIENT.
This commit is contained in:
parent
54aec5f678
commit
992ad62e3c
@ -32,6 +32,11 @@ struct httpclient {
|
||||
int timeout_server; /* server timeout in ms */
|
||||
void *caller; /* ptr of the caller */
|
||||
unsigned int flags; /* other flags */
|
||||
struct proxy *px; /* proxy for special cases */
|
||||
struct server *srv_raw; /* server for clear connections */
|
||||
#ifdef USE_OPENSSL
|
||||
struct server *srv_ssl; /* server for SSL connections */
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Action (FA) to do */
|
||||
|
@ -6,6 +6,8 @@
|
||||
void httpclient_destroy(struct httpclient *hc);
|
||||
void httpclient_stop_and_destroy(struct httpclient *hc);
|
||||
struct httpclient *httpclient_new(void *caller, enum http_meth_t meth, struct ist url);
|
||||
struct httpclient *httpclient_new_from_proxy(struct proxy *px, void *caller, enum http_meth_t meth, struct ist url);
|
||||
int httpclient_set_proxy(struct httpclient *hc, struct proxy *px);
|
||||
|
||||
struct appctx *httpclient_start(struct httpclient *hc);
|
||||
int httpclient_set_dst(struct httpclient *hc, const char *dst);
|
||||
|
@ -610,6 +610,8 @@ void httpclient_destroy(struct httpclient *hc)
|
||||
}
|
||||
|
||||
/* Allocate an httpclient and its buffers
|
||||
* Use the default httpclient_proxy
|
||||
*
|
||||
* Return NULL on failure */
|
||||
struct httpclient *httpclient_new(void *caller, enum http_meth_t meth, struct ist url)
|
||||
{
|
||||
@ -624,6 +626,7 @@ struct httpclient *httpclient_new(void *caller, enum http_meth_t meth, struct is
|
||||
hc->caller = caller;
|
||||
hc->req.url = istdup(url);
|
||||
hc->req.meth = meth;
|
||||
httpclient_set_proxy(hc, httpclient_proxy);
|
||||
|
||||
return hc;
|
||||
|
||||
@ -632,6 +635,49 @@ err:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate an httpclient and its buffers,
|
||||
* Use the proxy <px>
|
||||
*
|
||||
* Return and httpclient or NULL.
|
||||
*/
|
||||
struct httpclient *httpclient_new_from_proxy(struct proxy *px, void *caller, enum http_meth_t meth, struct ist url)
|
||||
{
|
||||
struct httpclient *hc;
|
||||
|
||||
hc = httpclient_new(caller, meth, url);
|
||||
if (!hc)
|
||||
return NULL;
|
||||
|
||||
httpclient_set_proxy(hc, px);
|
||||
|
||||
return hc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure an httpclient with a specific proxy <px>
|
||||
*
|
||||
* The proxy <px> must contains 2 srv, one configured for clear connections, the other for SSL.
|
||||
*
|
||||
*/
|
||||
int httpclient_set_proxy(struct httpclient *hc, struct proxy *px)
|
||||
{
|
||||
struct server *srv;
|
||||
|
||||
hc->px = px;
|
||||
|
||||
for (srv = px->srv; srv != NULL; srv = srv->next) {
|
||||
if (srv->xprt == xprt_get(XPRT_RAW)) {
|
||||
hc->srv_raw = srv;
|
||||
#ifdef USE_OPENSSL
|
||||
} else if (srv->xprt == xprt_get(XPRT_SSL)) {
|
||||
hc->srv_ssl = srv;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void httpclient_applet_io_handler(struct appctx *appctx)
|
||||
{
|
||||
struct httpclient *hc = appctx->svcctx;
|
||||
@ -974,12 +1020,12 @@ static int httpclient_applet_init(struct appctx *appctx)
|
||||
/* choose the SSL server or not */
|
||||
switch (scheme) {
|
||||
case SCH_HTTP:
|
||||
target = &httpclient_srv_raw->obj_type;
|
||||
target = &hc->srv_raw->obj_type;
|
||||
break;
|
||||
case SCH_HTTPS:
|
||||
#ifdef USE_OPENSSL
|
||||
if (httpclient_srv_ssl) {
|
||||
target = &httpclient_srv_ssl->obj_type;
|
||||
if (hc->srv_ssl) {
|
||||
target = &hc->srv_ssl->obj_type;
|
||||
} else {
|
||||
ha_alert("httpclient: SSL was disabled (wrong verify/ca-file)!\n");
|
||||
goto out_free_addr;
|
||||
@ -991,7 +1037,7 @@ static int httpclient_applet_init(struct appctx *appctx)
|
||||
break;
|
||||
}
|
||||
|
||||
if (appctx_finalize_startup(appctx, httpclient_proxy, &hc->req.buf) == -1) {
|
||||
if (appctx_finalize_startup(appctx, hc->px, &hc->req.buf) == -1) {
|
||||
ha_alert("httpclient: Failed to initialize appctx %s:%d.\n", __FUNCTION__, __LINE__);
|
||||
goto out_free_addr;
|
||||
}
|
||||
@ -1301,12 +1347,22 @@ static int httpclient_postcheck()
|
||||
{
|
||||
int err_code = ERR_NONE;
|
||||
struct logsrv *logsrv;
|
||||
struct proxy *curproxy = httpclient_proxy;
|
||||
struct proxy *curproxy = NULL;
|
||||
char *errmsg = NULL;
|
||||
#ifdef USE_OPENSSL
|
||||
struct server *srv = NULL;
|
||||
struct server *srv_ssl = NULL;
|
||||
#endif
|
||||
|
||||
if (global.mode & MODE_MWORKER_WAIT)
|
||||
return ERR_NONE;
|
||||
|
||||
/* Initialize the logs for every proxy dedicated to the httpclient */
|
||||
for (curproxy = proxies_list; curproxy; curproxy = curproxy->next) {
|
||||
|
||||
if (!(curproxy->cap & PR_CAP_HTTPCLIENT))
|
||||
continue;
|
||||
|
||||
/* copy logs from "global" log list */
|
||||
list_for_each_entry(logsrv, &global.logsrvs, list) {
|
||||
struct logsrv *node = malloc(sizeof(*node));
|
||||
@ -1337,17 +1393,25 @@ static int httpclient_postcheck()
|
||||
}
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
if (httpclient_srv_ssl) {
|
||||
/* initialize the SNI for the SSL servers */
|
||||
|
||||
for (srv = curproxy->srv; srv != NULL; srv = srv->next) {
|
||||
if (srv->xprt == xprt_get(XPRT_SSL)) {
|
||||
srv_ssl = srv;
|
||||
}
|
||||
}
|
||||
if (srv_ssl) {
|
||||
/* init the SNI expression */
|
||||
/* always use the host header as SNI, without the port */
|
||||
httpclient_srv_ssl->sni_expr = strdup("req.hdr(host),field(1,:)");
|
||||
err_code |= server_parse_sni_expr(httpclient_srv_ssl, httpclient_proxy, &errmsg);
|
||||
srv_ssl->sni_expr = strdup("req.hdr(host),field(1,:)");
|
||||
err_code |= server_parse_sni_expr(srv_ssl, curproxy, &errmsg);
|
||||
if (err_code & ERR_CODE) {
|
||||
memprintf(&errmsg, "failed to configure sni: %s.", errmsg);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
err:
|
||||
if (err_code & ERR_CODE) {
|
||||
|
Loading…
Reference in New Issue
Block a user