From a1814bb68021504e66747845c4303241a31a204c Mon Sep 17 00:00:00 2001 From: Mike Siomkin <msiomkin@mail.ru> Date: Tue, 19 Mar 2019 16:35:06 +0300 Subject: [PATCH] httpc: add proxy server options for curl Added support for the following curl options: * CURLOPT_PROXY * CURLOPT_PROXYPORT * CURLOPT_PROXYUSERPWD * CURLOPT_NOPROXY @TarantoolBot document Title: httpc: proxy server options Use 'proxy' option to specify the proxy server host or IP-address (optionally may be prefixed with a scheme - e.g. http:// or https://). 'proxy_port' and 'proxy_user_pwd' options may be used to specify the proxy port (443 for https proxy and 1080 for others by default) and user credentials (format: [user name]:[password]) respectively. If 'proxy' option is not set a value from the corresponding environment variable will be used. Environment variable names are: 'http_proxy', 'https_proxy', 'ftp_proxy' etc. 'all_proxy' variable is used if no protocol specific proxy was set. Setting 'proxy' option to an empty string will explicitly disable the use of a proxy, even if there is an environment variable set for it. Set 'no_proxy' option to specify a comma separated list of hosts that do not require a proxy to get reached, even if one is specified by 'proxy' option (or the corresponding environment variable). The only wildcard available is a single * character, which matches all hosts, and effectively disables the proxy. 'no_proxy' environment variable will be used if this option is not set. Setting 'no_proxy' option to an empty string will explicitly enable the proxy for all host names, even if there is an environment variable set for it. See: https://curl.haxx.se/libcurl/c/CURLOPT_PROXY.html https://curl.haxx.se/libcurl/c/CURLOPT_PROXYPORT.html https://curl.haxx.se/libcurl/c/CURLOPT_USERPWD.html https://curl.haxx.se/libcurl/c/CURLOPT_NOPROXY.html --- src/httpc.c | 25 ++++++++++++++++++++ src/httpc.h | 60 +++++++++++++++++++++++++++++++++++++++++++++++ src/lua/httpc.c | 20 ++++++++++++++++ src/lua/httpc.lua | 9 +++++++ 4 files changed, 114 insertions(+) diff --git a/src/httpc.c b/src/httpc.c index 54bc785e1b..8d18b9966a 100644 --- a/src/httpc.c +++ b/src/httpc.c @@ -324,6 +324,30 @@ httpc_set_ssl_cert(struct httpc_request *req, const char *ssl_cert) curl_easy_setopt(req->curl_request.easy, CURLOPT_SSLCERT, ssl_cert); } +void +httpc_set_proxy(struct httpc_request *req, const char *proxy) +{ + curl_easy_setopt(req->curl_request.easy, CURLOPT_PROXY, proxy); +} + +void +httpc_set_proxy_port(struct httpc_request *req, long port) +{ + curl_easy_setopt(req->curl_request.easy, CURLOPT_PROXYPORT, port); +} + +void +httpc_set_proxy_user_pwd(struct httpc_request *req, const char *user_pwd) +{ + curl_easy_setopt(req->curl_request.easy, CURLOPT_PROXYUSERPWD, user_pwd); +} + +void +httpc_set_no_proxy(struct httpc_request *req, const char *no_proxy) +{ + curl_easy_setopt(req->curl_request.easy, CURLOPT_NOPROXY, no_proxy); +} + void httpc_set_interface(struct httpc_request *req, const char *interface) { @@ -402,6 +426,7 @@ httpc_execute(struct httpc_request *req, double timeout) req->reason = curl_easy_strerror(req->curl_request.code); ++env->stat.failed_requests; break; + case CURLE_COULDNT_RESOLVE_PROXY: case CURLE_COULDNT_RESOLVE_HOST: case CURLE_COULDNT_CONNECT: /* 595 Connection Problem (AnyEvent non-standard) */ diff --git a/src/httpc.h b/src/httpc.h index c6882a534a..99fd8fbd43 100644 --- a/src/httpc.h +++ b/src/httpc.h @@ -291,6 +291,66 @@ httpc_set_ssl_key(struct httpc_request *req, const char *ssl_key); void httpc_set_ssl_cert(struct httpc_request *req, const char *ssl_cert); +/** + * Specify a proxy to use (optionally may be prefixed with a scheme - + * e.g. http:// or https://). + * + * If this option is not set a value from the corresponding + * environment variable will be used. Environment variable names are: + * 'http_proxy', 'https_proxy', 'ftp_proxy' etc. 'all_proxy' variable + * is used if no protocol specific proxy was set. + * + * Setting this option to an empty string will explicitly disable the + * use of a proxy, even if there is an environment variable set for it. + * + * @param req request + * @param proxy - a host name or an IP address. The application does not + * have to keep the string around after setting this option. + * @see https://curl.haxx.se/libcurl/c/CURLOPT_PROXY.html + */ +void +httpc_set_proxy(struct httpc_request *req, const char *proxy); + +/** + * Specify a port number the proxy listens on + * @param req request + * @param port - a port number the proxy listens on + * @see https://curl.haxx.se/libcurl/c/CURLOPT_PROXYPORT.html + */ +void +httpc_set_proxy_port(struct httpc_request *req, long port); + +/** + * Specify a user name and a password to use in authentication + * @param req request + * @param user_pwd - a login details string for the connection. + * The format is: [user name]:[password]. The application does not + * have to keep the string around after setting this option. + * @see https://curl.haxx.se/libcurl/c/CURLOPT_USERPWD.html + */ +void +httpc_set_proxy_user_pwd(struct httpc_request *req, const char *user_pwd); + +/** + * Specify a comma separated list of host names that do not require a proxy + * to get reached, even if one is specified by 'proxy' option. The only + * wildcard available is a single * character, which matches all hosts, and + * effectively disables the proxy. + * + * 'no_proxy' environment variable will be used if this option is not set. + * + * Setting this option to an empty string will + * explicitly enable the proxy for all host names, even if there is an + * environment variable set for it. + * + * @param req request + * @param no_proxy - a comma separated list of host names. The application + * does not have to keep the string around after setting this option. + * @see https://curl.haxx.se/libcurl/c/CURLOPT_NOPROXY.html + */ +void +httpc_set_no_proxy(struct httpc_request *req, const char *no_proxy); + /** * Specify source interface for outgoing traffic * @param req request diff --git a/src/lua/httpc.c b/src/lua/httpc.c index e02adb9fb9..a8e3e2525b 100644 --- a/src/lua/httpc.c +++ b/src/lua/httpc.c @@ -243,6 +243,26 @@ luaT_httpc_request(lua_State *L) httpc_set_ssl_cert(req, lua_tostring(L, -1)); lua_pop(L, 1); + lua_getfield(L, 5, "proxy"); + if (!lua_isnil(L, -1)) + httpc_set_proxy(req, lua_tostring(L, -1)); + lua_pop(L, 1); + + lua_getfield(L, 5, "proxy_port"); + if (!lua_isnil(L, -1)) + httpc_set_proxy_port(req, (long) lua_tonumber(L, -1)); + lua_pop(L, 1); + + lua_getfield(L, 5, "proxy_user_pwd"); + if (!lua_isnil(L, -1)) + httpc_set_proxy_user_pwd(req, lua_tostring(L, -1)); + lua_pop(L, 1); + + lua_getfield(L, 5, "no_proxy"); + if (!lua_isnil(L, -1)) + httpc_set_no_proxy(req, lua_tostring(L, -1)); + lua_pop(L, 1); + long keepalive_idle = 0; long keepalive_interval = 0; diff --git a/src/lua/httpc.lua b/src/lua/httpc.lua index 50ff91a369..ce9bb9771e 100644 --- a/src/lua/httpc.lua +++ b/src/lua/httpc.lua @@ -258,6 +258,15 @@ end -- -- ssl_cert - set path to the file with SSL client certificate; -- +-- proxy - set a proxy to use; +-- +-- proxy_port - set a port number the proxy listens on; +-- +-- proxy_user_pwd - set a user name and a password to use +-- in authentication; +-- +-- no_proxy - disable proxy use for specific hosts; +-- -- headers - a table of HTTP headers; -- -- keepalive_idle & keepalive_interval - -- GitLab