Commit 3757bc5e authored by Alexey Botchkov's avatar Alexey Botchkov

MDEV-8431 Feedback plugin needs an option for http proxy.

'feedback_http_proxy' system variable added to specify the
proxy server as host:port. Not a dynamic one.
parent 16ad1fc5
......@@ -25,7 +25,7 @@ namespace feedback {
char server_uid_buf[SERVER_UID_SIZE+1]; ///< server uid will be written here
/* backing store for system variables */
static char *server_uid= server_uid_buf, *url;
static char *server_uid= server_uid_buf, *url, *http_proxy;
char *user_info;
ulong send_timeout, send_retry_wait;
......@@ -272,7 +272,13 @@ static int init(void *p)
if (*e == 0 || *e == ' ')
{
if (e > s && (urls[slot]= Url::create(s, e - s)))
{
if (urls[slot]->set_proxy(http_proxy,
http_proxy ? strlen(http_proxy) : 0))
sql_print_error("feedback plugin: invalid proxy '%s'",
http_proxy ? http_proxy : "");
slot++;
}
else
{
if (e > s)
......@@ -350,6 +356,10 @@ static MYSQL_SYSVAR_ULONG(send_timeout, send_timeout, PLUGIN_VAR_RQCMDARG,
static MYSQL_SYSVAR_ULONG(send_retry_wait, send_retry_wait, PLUGIN_VAR_RQCMDARG,
"Wait this many seconds before retrying a failed send.",
NULL, NULL, 60, 1, 60*60*24, 1);
static MYSQL_SYSVAR_STR(http_proxy, http_proxy,
PLUGIN_VAR_READONLY | PLUGIN_VAR_RQCMDARG,
"Proxy server host:port.", NULL, NULL,0);
static struct st_mysql_sys_var* settings[] = {
MYSQL_SYSVAR(server_uid),
......@@ -357,6 +367,7 @@ static struct st_mysql_sys_var* settings[] = {
MYSQL_SYSVAR(url),
MYSQL_SYSVAR(send_timeout),
MYSQL_SYSVAR(send_retry_wait),
MYSQL_SYSVAR(http_proxy),
NULL
};
......
......@@ -52,8 +52,14 @@ class Url {
const char *url() { return full_url.str; }
size_t url_length() { return full_url.length; }
virtual int send(const char* data, size_t data_length) = 0;
virtual int set_proxy(const char *proxy, size_t proxy_len)
{
return 0;
}
static Url* create(const char *url, size_t url_length);
static int parse_proxy_server(const char *proxy_server, size_t proxy_length,
LEX_STRING *host, LEX_STRING *port);
};
extern Url **urls;
......
......@@ -48,4 +48,50 @@ Url* Url::create(const char *url, size_t url_length)
return self;
}
int Url::parse_proxy_server(const char *proxy_server, size_t proxy_length,
LEX_STRING *host, LEX_STRING *port)
{
const char *s;
host->length= 0;
if (proxy_server == NULL)
return 0;
for (; proxy_length > 0 && isspace(*proxy_server);
proxy_server++, proxy_length--) /* no-op */;
if (proxy_length == 0)
return 0;
for (s=proxy_server; *s && *s != ':'; s++) /* no-op */;
host->str= const_cast<char*>(proxy_server);
if ((host->length= s-proxy_server) == 0)
return 0;
port->length= 0;
if (*s == ':')
{
s++;
port->str= const_cast<char*>(s);
while (*s >= '0' && *s <= '9')
{
s++;
port->length++;
}
}
if (port->length == 0)
{
port->str= const_cast<char*>("80");
port->length= 2;
}
host->str= my_strndup(host->str, host->length, MYF(MY_WME));
port->str= my_strndup(port->str, port->length, MYF(MY_WME));
return 0;
}
} // namespace feedback
......@@ -38,20 +38,39 @@ class Url_http: public Url {
protected:
const LEX_STRING host, port, path;
bool ssl;
LEX_STRING proxy_host, proxy_port;
int use_proxy()
{
return proxy_host.length;
}
Url_http(LEX_STRING &url_arg, LEX_STRING &host_arg,
LEX_STRING &port_arg, LEX_STRING &path_arg, bool ssl_arg) :
Url(url_arg), host(host_arg), port(port_arg), path(path_arg), ssl(ssl_arg)
{}
{
proxy_host.length= 0;
}
~Url_http()
{
my_free(host.str);
my_free(port.str);
my_free(path.str);
set_proxy(0,0);
}
public:
int send(const char* data, size_t data_length);
int set_proxy(const char *proxy, size_t proxy_len)
{
if (use_proxy())
{
my_free(proxy_host.str);
my_free(proxy_port.str);
}
return parse_proxy_server(proxy, proxy_len, &proxy_host, &proxy_port);
}
friend Url* http_create(const char *url, size_t url_length);
};
......@@ -150,7 +169,9 @@ int Url_http::send(const char* data, size_t data_length)
uint len= 0;
addrinfo *addrs, *addr, filter= {0, AF_UNSPEC, SOCK_STREAM, 6, 0, 0, 0, 0};
int res= getaddrinfo(host.str, port.str, &filter, &addrs);
int res= use_proxy() ?
getaddrinfo(proxy_host.str, proxy_port.str, &filter, &addrs) :
getaddrinfo(host.str, port.str, &filter, &addrs);
if (res)
{
......@@ -228,16 +249,20 @@ int Url_http::send(const char* data, size_t data_length)
};
len= my_snprintf(buf, sizeof(buf),
"POST %s HTTP/1.0\r\n"
"User-Agent: MariaDB User Feedback Plugin\r\n"
"Host: %s:%s\r\n"
"Accept: */*\r\n"
"Content-Length: %u\r\n"
"Content-Type: multipart/form-data; boundary=%s\r\n"
"\r\n",
path.str, host.str, port.str,
(uint)(2*boundary.length + header.length + data_length + 4),
boundary.str + 2);
use_proxy() ? "POST http://%s:%s/" : "POST ",
host.str, port.str);
len+= my_snprintf(buf+len, sizeof(buf)-len,
"%s HTTP/1.0\r\n"
"User-Agent: MariaDB User Feedback Plugin\r\n"
"Host: %s:%s\r\n"
"Accept: */*\r\n"
"Content-Length: %u\r\n"
"Content-Type: multipart/form-data; boundary=%s\r\n"
"\r\n",
path.str, host.str, port.str,
(uint)(2*boundary.length + header.length + data_length + 4),
boundary.str + 2);
vio_timeout(vio, FOR_READING, send_timeout);
vio_timeout(vio, FOR_WRITING, send_timeout);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment