diff --git a/checkin_notes b/checkin_notes index 33f556bb05..2a219b12c5 100644 --- a/checkin_notes +++ b/checkin_notes @@ -8953,3 +8953,17 @@ David 6 Nov 2009 db/ boinc_db.cpp + +David 6 Nov 2009 + - client: parse HTTP_PROXY strings of the form + http://username:passwd@host.dom.dom:port/file + (we weren't parsing the username and password before). + - client: fix the feature that lets you exclude a list of hosts + from going the proxy. + + client/ + cs_cmdline.cpp + http_curl.cpp + sysmon_win.cpp + lib/ + url.cpp,h diff --git a/client/cs_cmdline.cpp b/client/cs_cmdline.cpp index fcad062ba7..9aee84222e 100644 --- a/client/cs_cmdline.cpp +++ b/client/cs_cmdline.cpp @@ -247,11 +247,25 @@ void CLIENT_STATE::parse_env_vars() { char *p; char temp[256]; int proto; + PARSED_URL purl; p = getenv("HTTP_PROXY"); if (p && strlen(p) > 0) { - proxy_info.use_http_proxy = true; - parse_url(p, proto, proxy_info.http_server_name, proxy_info.http_server_port, temp); + parse_url(p, purl); + switch (purl.protocol) { + case URL_PROTOCOL_HTTP: + case URL_PROTOCOL_HTTPS: + proxy_info.use_http_proxy = true; + strcpy(proxy_info.http_user_name, purl.user); + strcpy(proxy_info.http_user_passwd, purl.passwd); + strcpy(proxy_info.http_server_name, purl.host); + proxy_info.http_server_port = purl.port; + break; + default: + msg_printf(0, MSG_USER_ERROR, + "The HTTP_PROXY environment variable must specify an HTTP proxy" + ); + } } p = getenv("HTTP_USER_NAME"); if (p) { @@ -266,8 +280,12 @@ void CLIENT_STATE::parse_env_vars() { p = getenv("SOCKS_SERVER"); if (!p) p = getenv("SOCKS5_SERVER"); if (p && strlen(p)) { + parse_url(p, purl); proxy_info.use_socks_proxy = true; - parse_url(p, proto, proxy_info.socks_server_name, proxy_info.socks_server_port, temp); + strcpy(proxy_info.socks5_user_name, purl.user); + strcpy(proxy_info.socks5_user_passwd, purl.passwd); + strcpy(proxy_info.socks_server_name, purl.host); + proxy_info.socks_server_port = purl.port; } p = getenv("SOCKS5_USER"); diff --git a/client/http_curl.cpp b/client/http_curl.cpp index ec17ab67a0..6fdb4e5892 100644 --- a/client/http_curl.cpp +++ b/client/http_curl.cpp @@ -202,27 +202,23 @@ int HTTP_OP::init_post2( // is URL in proxy exception list? // bool HTTP_OP::no_proxy_for_url(const char* url) { + PARSED_URL purl, purl2; + char noproxy[256]; + if (log_flags.proxy_debug) { msg_printf(0, MSG_INFO, "[proxy_debug] HTTP_OP::no_proxy_for_url(): %s", url); } - char hosturl[256]; - char file[256]; - char hostnoproxy[256]; - char noproxy[256]; - int protocol; - int port; - // extract the host from the url - parse_url(url, protocol, hosturl, port, file); + parse_url(url, purl); // tokenize the noproxy-entry and check for identical hosts // strcpy(noproxy, gstate.proxy_info.noproxy_hosts); char* token = strtok(noproxy, ","); - while(token!= NULL) { + while (token != NULL) { // extract the host from the no_proxy url - parse_url(token, protocol, hostnoproxy, port, file); - if (hostnoproxy == hosturl) { + parse_url(token, purl2); + if (!strcmp(purl.host, purl2.host)) { if (log_flags.proxy_debug) { msg_printf(0, MSG_INFO, "[proxy_debug] disabling proxy for %s", url); } diff --git a/client/sysmon_win.cpp b/client/sysmon_win.cpp index 61664cb069..3dac43b613 100644 --- a/client/sysmon_win.cpp +++ b/client/sysmon_win.cpp @@ -125,10 +125,7 @@ static void windows_detect_autoproxy_settings() { HINTERNET hWinHttp = NULL; WINHTTP_AUTOPROXY_OPTIONS autoproxy_options; WINHTTP_PROXY_INFO proxy_info; - int proxy_protocol = 0; - char proxy_server[256]; - int proxy_port = 0; - char proxy_file[256]; + PARSED_URL purl; std::wstring network_test_url; size_t pos; @@ -191,22 +188,21 @@ static void windows_detect_autoproxy_settings() { } // Parse the remaining url - parse_url( - proxy.c_str(), + parse_url(proxy.c_str(), purl); proxy_protocol, proxy_server, proxy_port, proxy_file - ); // Store the results for future use. - gstate.proxy_info.autodetect_protocol = proxy_protocol; - strcpy(gstate.proxy_info.autodetect_server_name, proxy_server); - gstate.proxy_info.autodetect_port = proxy_port; + gstate.proxy_info.autodetect_protocol = purl.protocol; + strcpy(gstate.proxy_info.autodetect_server_name, purl.host); + gstate.proxy_info.autodetect_port = purl.port; if (log_flags.proxy_debug) { msg_printf(NULL, MSG_INFO, - "[proxy_debug] automatic proxy detected %s:%d", proxy_server, proxy_port + "[proxy_debug] automatic proxy detected %s:%d", + purl.host, purl.port ); } } diff --git a/lib/url.cpp b/lib/url.cpp index 3779871c60..e624b19993 100644 --- a/lib/url.cpp +++ b/lib/url.cpp @@ -31,52 +31,71 @@ using std::string; // URL format: // [{http|https|socks}://][user[:passwd]@]host.dom.dom[:port][/dir/file] // -void parse_url(const char* url, int &protocol, char* host, int &port, char* file) { - char* p; - char buf[256]; +void parse_url(const char* url, PARSED_URL& purl) { + char* p, *q, *buf; + char _buf[256]; // strip off the protocol if present // if (strncmp(url, "http://", 7) == 0) { - safe_strcpy(buf, url+7); - protocol = URL_PROTOCOL_HTTP; + safe_strcpy(_buf, url+7); + purl.protocol = URL_PROTOCOL_HTTP; } else if (strncmp(url, "https://", 8) == 0) { - safe_strcpy(buf, url+8); - protocol = URL_PROTOCOL_HTTPS; + safe_strcpy(_buf, url+8); + purl.protocol = URL_PROTOCOL_HTTPS; } else if (strncmp(url, "socks://", 8) == 0) { - safe_strcpy(buf, url+8); - protocol = URL_PROTOCOL_SOCKS; + safe_strcpy(_buf, url+8); + purl.protocol = URL_PROTOCOL_SOCKS; } else { - safe_strcpy(buf, url); - protocol = URL_PROTOCOL_UNKNOWN; + safe_strcpy(_buf, url); + purl.protocol = URL_PROTOCOL_UNKNOWN; + } + buf = _buf; + + // parse user name and password + // + strcpy(purl.user, ""); + strcpy(purl.passwd, ""); + p = strchr(buf, '@'); + if (p) { + *p = 0; + q = strchr(buf, ':'); + if (q) { + *q = 0; + strcpy(purl.user, buf); + strcpy(purl.passwd, q+1); + } else { + strcpy(purl.user, buf); + } + buf = p+1; } // parse and strip off file part if present // p = strchr(buf, '/'); if (p) { - strcpy(file, p+1); + strcpy(purl.file, p+1); *p = 0; } else { - strcpy(file, ""); + strcpy(purl.file, ""); } // parse and strip off port if present // p = strchr(buf,':'); if (p) { - port = atol(p+1); + purl.port = atol(p+1); *p = 0; } else { // CMC note: if they didn't pass in a port #, // but the url starts with https://, assume they // want a secure port (HTTPS, port 443) - port = (protocol == URL_PROTOCOL_HTTPS) ? 443 : 80; + purl.port = (purl.protocol == URL_PROTOCOL_HTTPS) ? 443 : 80; } // what remains is the host // - strcpy(host, buf); + strcpy(purl.host, buf); } static char x2c(char *what) { diff --git a/lib/url.h b/lib/url.h index 055f1ddabb..f48cfaa14c 100644 --- a/lib/url.h +++ b/lib/url.h @@ -20,9 +20,16 @@ #define URL_PROTOCOL_HTTPS 2 #define URL_PROTOCOL_SOCKS 3 -extern void parse_url( - const char* url, int &protocol, char* host, int &port, char* file -); +struct PARSED_URL { + int protocol; + char user[256]; + char passwd[256]; + char host[256]; + int port; + char file[256]; +}; + +extern void parse_url(const char* url, PARSED_URL&); extern void unescape_url(std::string& url); extern void unescape_url(char *url); extern void escape_url(std::string& url);