From 83614a9fbe650c57c0c80672c59216a553011ef4 Mon Sep 17 00:00:00 2001 From: William Lallemand Date: Fri, 13 Aug 2021 14:47:57 +0200 Subject: [PATCH] MINOR: httpclient: initialize the proxy Initialize a proxy which contain a server for the raw HTTP, and another one for the HTTPS. This proxy will use the global server log definition and the 'option httplog' directive. This proxy is internal and will only be used for the HTTP Client API. --- Makefile | 3 +- src/http_client.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 src/http_client.c diff --git a/Makefile b/Makefile index e88ab302ea..84b1bc0ea7 100644 --- a/Makefile +++ b/Makefile @@ -886,7 +886,8 @@ OBJS += src/mux_h2.o src/mux_fcgi.o src/http_ana.o src/mux_h1.o src/stream.o \ src/hpack-tbl.o src/ebimtree.o src/auth.o src/ebsttree.o \ src/ebistree.o src/base64.o src/wdt.o src/pipe.o src/http_acl.o \ src/hpack-enc.o src/dict.o src/dgram.o src/init.o src/hpack-huff.o \ - src/freq_ctr.o src/ebtree.o src/hash.o src/version.o src/errors.o + src/freq_ctr.o src/ebtree.o src/hash.o src/version.o src/errors.o \ + src/http_client.o ifneq ($(TRACE),) OBJS += src/calltrace.o diff --git a/src/http_client.c b/src/http_client.c new file mode 100644 index 0000000000..4a95b9237b --- /dev/null +++ b/src/http_client.c @@ -0,0 +1,154 @@ +/* + * HTTP Client + * + * Copyright (C) 2021 HAProxy Technologies, William Lallemand + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * This file implements an HTTP Client API. + * + */ +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + + +static struct proxy *httpclient_proxy; +static struct server *httpclient_srv_raw; +static struct server *httpclient_srv_ssl; + +/* + * Initialize the proxy for the HTTP client with 2 servers, one for raw HTTP, + * the other for HTTPS. + */ + +static int httpclient_init() +{ + int err_code = 0; + char *errmsg = NULL; + + httpclient_proxy = alloc_new_proxy("", PR_CAP_LISTEN|PR_CAP_INT, &errmsg); + if (!httpclient_proxy) { + err_code |= ERR_ALERT | ERR_FATAL; + goto err; + } + + httpclient_proxy->options2 |= PR_O2_INDEPSTR; + httpclient_proxy->mode = PR_MODE_HTTP; + httpclient_proxy->maxconn = 0; + httpclient_proxy->accept = NULL; + httpclient_proxy->timeout.client = TICK_ETERNITY; + /* The HTTP Client use the "option httplog" with the global log server */ + httpclient_proxy->conf.logformat_string = default_http_log_format; + httpclient_proxy->http_needed = 1; + + /* clear HTTP server */ + httpclient_srv_raw = new_server(httpclient_proxy); + if (!httpclient_srv_raw) { + err_code |= ERR_ALERT | ERR_FATAL; + memprintf(&errmsg, "out of memory."); + goto err; + } + + httpclient_srv_raw->iweight = 0; + httpclient_srv_raw->uweight = 0; + httpclient_srv_raw->xprt = xprt_get(XPRT_RAW); + httpclient_srv_raw->id = strdup(""); + if (!httpclient_srv_raw->id) + goto err; + + /* SSL HTTP server */ + httpclient_srv_ssl = new_server(httpclient_proxy); + if (!httpclient_srv_ssl) { + memprintf(&errmsg, "out of memory."); + err_code |= ERR_ALERT | ERR_FATAL; + goto err; + } + httpclient_srv_ssl->iweight = 0; + httpclient_srv_ssl->uweight = 0; + httpclient_srv_ssl->xprt = xprt_get(XPRT_SSL); + httpclient_srv_ssl->use_ssl = 1; + httpclient_srv_ssl->id = strdup(""); + if (!httpclient_srv_ssl->id) + goto err; + + /* add the proxy in the proxy list only if everything successed */ + httpclient_proxy->next = proxies_list; + proxies_list = httpclient_proxy; + + return 0; + +err: + ha_alert("httpclient: cannot initialize.\n"); + free(errmsg); + free_server(httpclient_srv_raw); + free_server(httpclient_srv_ssl); + free_proxy(httpclient_proxy); + return err_code; +} + +/* + * Post config parser callback, this is used to copy the log line from the + * global section and put it in the server proxy + */ +static int httpclient_cfg_postparser() +{ + struct logsrv *logsrv; + struct proxy *curproxy = httpclient_proxy; + + /* copy logs from "global" log list */ + list_for_each_entry(logsrv, &global.logsrvs, list) { + struct logsrv *node = malloc(sizeof(*node)); + + if (!node) { + ha_alert("httpclient: cannot allocate memory.\n"); + goto err; + } + + memcpy(node, logsrv, sizeof(*node)); + LIST_INIT(&node->list); + LIST_APPEND(&curproxy->logsrvs, &node->list); + } + if (curproxy->conf.logformat_string) { + char *err = NULL; + + curproxy->conf.args.ctx = ARGC_LOG; + if (!parse_logformat_string(curproxy->conf.logformat_string, curproxy, &curproxy->logformat, + LOG_OPT_MANDATORY|LOG_OPT_MERGE_SPACES, + SMP_VAL_FE_LOG_END, &err)) { + ha_alert("httpclient: failed to parse log-format : %s.\n", err); + free(err); + goto err; + } + curproxy->conf.args.file = NULL; + curproxy->conf.args.line = 0; + } + return 0; +err: + return 1; +} + +static void httpclient_deinit() +{ + free_server(httpclient_srv_raw); + free_server(httpclient_srv_ssl); + free_proxy(httpclient_proxy); + +} + +/* initialize the proxy and servers for the HTTP client */ + +INITCALL0(STG_REGISTER, httpclient_init); +REGISTER_CONFIG_POSTPARSER("httpclient", httpclient_cfg_postparser); +REGISTER_POST_DEINIT(httpclient_deinit); -- 2.39.5