Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(603)

Side by Side Diff: webrtc/base/proxydetect.cc

Issue 2541453002: Delete unused classes AutoDetectProxy and SslSocketFactory. (Closed)
Patch Set: Rebased. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/base/proxydetect.h ('k') | webrtc/base/proxydetect_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "webrtc/base/proxydetect.h"
12
13 #if defined(WEBRTC_WIN)
14 #include "webrtc/base/win32.h"
15 #include <shlobj.h>
16 #endif // WEBRTC_WIN
17
18 #if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
19 #include <SystemConfiguration/SystemConfiguration.h>
20 #include <CoreFoundation/CoreFoundation.h>
21 #include <CoreServices/CoreServices.h>
22 #include <Security/Security.h>
23 #include "macconversion.h"
24 #include "webrtc/base/unixfilesystem.h"
25 #endif
26
27 #ifdef WEBRTC_IOS
28 #include <CFNetwork/CFNetwork.h>
29 #include "macconversion.h"
30 #endif
31
32 #include <map>
33 #include <memory>
34
35 #include "webrtc/base/arraysize.h"
36 #include "webrtc/base/checks.h"
37 #include "webrtc/base/common.h"
38 #include "webrtc/base/fileutils.h"
39 #include "webrtc/base/httpcommon.h"
40 #include "webrtc/base/httpcommon-inl.h"
41 #include "webrtc/base/pathutils.h"
42 #include "webrtc/base/stringutils.h"
43
44 #define _TRY_JSPROXY 0
45 #define _TRY_WM_FINDPROXY 0
46
47 #if defined(WEBRTC_WIN)
48 #define _TRY_WINHTTP 1
49 #define _TRY_IE_LAN_SETTINGS 1
50 #else
51 #define _TRY_WINHTTP 0
52 #define _TRY_IE_LAN_SETTINGS 0
53 #endif // WEBRTC_WIN
54
55 // For all platforms try Firefox.
56 #define _TRY_FIREFOX 1
57
58 // Use profiles.ini to find the correct profile for this user.
59 // If not set, we'll just look for the default one.
60 #define USE_FIREFOX_PROFILES_INI 1
61
62 static const size_t kMaxLineLength = 1024;
63 static const char kFirefoxPattern[] = "Firefox";
64 static const char kInternetExplorerPattern[] = "MSIE";
65
66 struct StringMap {
67 public:
68 void Add(const char * name, const char * value) { map_[name] = value; }
69 const std::string& Get(const char * name, const char * def = "") const {
70 std::map<std::string, std::string>::const_iterator it =
71 map_.find(name);
72 if (it != map_.end())
73 return it->second;
74 def_ = def;
75 return def_;
76 }
77 bool IsSet(const char * name) const {
78 return (map_.find(name) != map_.end());
79 }
80 private:
81 std::map<std::string, std::string> map_;
82 mutable std::string def_;
83 };
84
85 enum UserAgent {
86 UA_FIREFOX,
87 UA_INTERNETEXPLORER,
88 UA_OTHER,
89 UA_UNKNOWN
90 };
91
92 #if _TRY_WINHTTP
93 //#include <winhttp.h>
94 // Note: From winhttp.h
95
96 const char WINHTTP[] = "winhttp";
97
98 typedef LPVOID HINTERNET;
99
100 typedef struct {
101 DWORD dwAccessType; // see WINHTTP_ACCESS_* types below
102 LPWSTR lpszProxy; // proxy server list
103 LPWSTR lpszProxyBypass; // proxy bypass list
104 } WINHTTP_PROXY_INFO, * LPWINHTTP_PROXY_INFO;
105
106 typedef struct {
107 DWORD dwFlags;
108 DWORD dwAutoDetectFlags;
109 LPCWSTR lpszAutoConfigUrl;
110 LPVOID lpvReserved;
111 DWORD dwReserved;
112 BOOL fAutoLogonIfChallenged;
113 } WINHTTP_AUTOPROXY_OPTIONS;
114
115 typedef struct {
116 BOOL fAutoDetect;
117 LPWSTR lpszAutoConfigUrl;
118 LPWSTR lpszProxy;
119 LPWSTR lpszProxyBypass;
120 } WINHTTP_CURRENT_USER_IE_PROXY_CONFIG;
121
122 extern "C" {
123 typedef HINTERNET (WINAPI * pfnWinHttpOpen)
124 (
125 IN LPCWSTR pwszUserAgent,
126 IN DWORD dwAccessType,
127 IN LPCWSTR pwszProxyName OPTIONAL,
128 IN LPCWSTR pwszProxyBypass OPTIONAL,
129 IN DWORD dwFlags
130 );
131 typedef BOOL (STDAPICALLTYPE * pfnWinHttpCloseHandle)
132 (
133 IN HINTERNET hInternet
134 );
135 typedef BOOL (STDAPICALLTYPE * pfnWinHttpGetProxyForUrl)
136 (
137 IN HINTERNET hSession,
138 IN LPCWSTR lpcwszUrl,
139 IN WINHTTP_AUTOPROXY_OPTIONS * pAutoProxyOptions,
140 OUT WINHTTP_PROXY_INFO * pProxyInfo
141 );
142 typedef BOOL (STDAPICALLTYPE * pfnWinHttpGetIEProxyConfig)
143 (
144 IN OUT WINHTTP_CURRENT_USER_IE_PROXY_CONFIG * pProxyConfig
145 );
146
147 } // extern "C"
148
149 #define WINHTTP_AUTOPROXY_AUTO_DETECT 0x00000001
150 #define WINHTTP_AUTOPROXY_CONFIG_URL 0x00000002
151 #define WINHTTP_AUTOPROXY_RUN_INPROCESS 0x00010000
152 #define WINHTTP_AUTOPROXY_RUN_OUTPROCESS_ONLY 0x00020000
153 #define WINHTTP_AUTO_DETECT_TYPE_DHCP 0x00000001
154 #define WINHTTP_AUTO_DETECT_TYPE_DNS_A 0x00000002
155 #define WINHTTP_ACCESS_TYPE_DEFAULT_PROXY 0
156 #define WINHTTP_ACCESS_TYPE_NO_PROXY 1
157 #define WINHTTP_ACCESS_TYPE_NAMED_PROXY 3
158 #define WINHTTP_NO_PROXY_NAME NULL
159 #define WINHTTP_NO_PROXY_BYPASS NULL
160
161 #endif // _TRY_WINHTTP
162
163 #if _TRY_JSPROXY
164 extern "C" {
165 typedef BOOL (STDAPICALLTYPE * pfnInternetGetProxyInfo)
166 (
167 LPCSTR lpszUrl,
168 DWORD dwUrlLength,
169 LPSTR lpszUrlHostName,
170 DWORD dwUrlHostNameLength,
171 LPSTR * lplpszProxyHostName,
172 LPDWORD lpdwProxyHostNameLength
173 );
174 } // extern "C"
175 #endif // _TRY_JSPROXY
176
177 #if _TRY_WM_FINDPROXY
178 #include <comutil.h>
179 #include <wmnetsourcecreator.h>
180 #include <wmsinternaladminnetsource.h>
181 #endif // _TRY_WM_FINDPROXY
182
183 #if _TRY_IE_LAN_SETTINGS
184 #include <wininet.h>
185 #include <string>
186 #endif // _TRY_IE_LAN_SETTINGS
187
188 namespace rtc {
189
190 //////////////////////////////////////////////////////////////////////
191 // Utility Functions
192 //////////////////////////////////////////////////////////////////////
193
194 #if defined(WEBRTC_WIN)
195 #ifdef _UNICODE
196
197 typedef std::wstring tstring;
198 std::string Utf8String(const tstring& str) { return ToUtf8(str); }
199
200 #else // !_UNICODE
201
202 typedef std::string tstring;
203 std::string Utf8String(const tstring& str) { return str; }
204
205 #endif // !_UNICODE
206 #endif // WEBRTC_WIN
207
208 bool ProxyItemMatch(const Url<char>& url, char * item, size_t len) {
209 // hostname:443
210 if (char * port = ::strchr(item, ':')) {
211 *port++ = '\0';
212 if (url.port() != atol(port)) {
213 return false;
214 }
215 }
216
217 // A.B.C.D or A.B.C.D/24
218 int a, b, c, d, m;
219 int match = sscanf(item, "%d.%d.%d.%d/%d", &a, &b, &c, &d, &m);
220 if (match >= 4) {
221 uint32_t ip = ((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) |
222 (d & 0xFF);
223 if ((match < 5) || (m > 32))
224 m = 32;
225 else if (m < 0)
226 m = 0;
227 uint32_t mask = (m == 0) ? 0 : (~0UL) << (32 - m);
228 SocketAddress addr(url.host(), 0);
229 // TODO: Support IPv6 proxyitems. This code block is IPv4 only anyway.
230 return !addr.IsUnresolvedIP() &&
231 ((addr.ipaddr().v4AddressAsHostOrderInteger() & mask) == (ip & mask));
232 }
233
234 // .foo.com
235 if (*item == '.') {
236 size_t hostlen = url.host().length();
237 return (hostlen > len)
238 && (stricmp(url.host().c_str() + (hostlen - len), item) == 0);
239 }
240
241 // localhost or www.*.com
242 if (!string_match(url.host().c_str(), item))
243 return false;
244
245 return true;
246 }
247
248 bool ProxyListMatch(const Url<char>& url, const std::string& proxy_list,
249 char sep) {
250 const size_t BUFSIZE = 256;
251 char buffer[BUFSIZE];
252 const char* list = proxy_list.c_str();
253 while (*list) {
254 // Remove leading space
255 if (isspace(*list)) {
256 ++list;
257 continue;
258 }
259 // Break on separator
260 size_t len;
261 const char * start = list;
262 if (const char * end = ::strchr(list, sep)) {
263 len = (end - list);
264 list += len + 1;
265 } else {
266 len = strlen(list);
267 list += len;
268 }
269 // Remove trailing space
270 while ((len > 0) && isspace(start[len-1]))
271 --len;
272 // Check for oversized entry
273 if (len >= BUFSIZE)
274 continue;
275 memcpy(buffer, start, len);
276 buffer[len] = 0;
277 if (!ProxyItemMatch(url, buffer, len))
278 continue;
279 return true;
280 }
281 return false;
282 }
283
284 bool Better(ProxyType lhs, const ProxyType rhs) {
285 // PROXY_NONE, PROXY_HTTPS, PROXY_SOCKS5, PROXY_UNKNOWN
286 const int PROXY_VALUE[5] = { 0, 2, 3, 1 };
287 return (PROXY_VALUE[lhs] > PROXY_VALUE[rhs]);
288 }
289
290 bool ParseProxy(const std::string& saddress, ProxyInfo* proxy) {
291 const size_t kMaxAddressLength = 1024;
292 // Allow semicolon, space, or tab as an address separator
293 const char* const kAddressSeparator = " ;\t";
294
295 ProxyType ptype;
296 std::string host;
297 uint16_t port;
298
299 const char* address = saddress.c_str();
300 while (*address) {
301 size_t len;
302 const char * start = address;
303 if (const char * sep = strchr(address, kAddressSeparator)) {
304 len = (sep - address);
305 address += len + 1;
306 while (*address != '\0' && ::strchr(kAddressSeparator, *address)) {
307 address += 1;
308 }
309 } else {
310 len = strlen(address);
311 address += len;
312 }
313
314 if (len > kMaxAddressLength - 1) {
315 LOG(LS_WARNING) << "Proxy address too long [" << start << "]";
316 continue;
317 }
318
319 char buffer[kMaxAddressLength];
320 memcpy(buffer, start, len);
321 buffer[len] = 0;
322
323 char * colon = ::strchr(buffer, ':');
324 if (!colon) {
325 LOG(LS_WARNING) << "Proxy address without port [" << buffer << "]";
326 continue;
327 }
328
329 *colon = 0;
330 char * endptr;
331 port = static_cast<uint16_t>(strtol(colon + 1, &endptr, 0));
332 if (*endptr != 0) {
333 LOG(LS_WARNING) << "Proxy address with invalid port [" << buffer << "]";
334 continue;
335 }
336
337 if (char * equals = ::strchr(buffer, '=')) {
338 *equals = 0;
339 host = equals + 1;
340 if (_stricmp(buffer, "socks") == 0) {
341 ptype = PROXY_SOCKS5;
342 } else if (_stricmp(buffer, "https") == 0) {
343 ptype = PROXY_HTTPS;
344 } else {
345 LOG(LS_WARNING) << "Proxy address with unknown protocol ["
346 << buffer << "]";
347 ptype = PROXY_UNKNOWN;
348 }
349 } else {
350 host = buffer;
351 ptype = PROXY_UNKNOWN;
352 }
353
354 if (Better(ptype, proxy->type)) {
355 proxy->type = ptype;
356 proxy->address.SetIP(host);
357 proxy->address.SetPort(port);
358 }
359 }
360
361 return proxy->type != PROXY_NONE;
362 }
363
364 UserAgent GetAgent(const char* agent) {
365 if (agent) {
366 std::string agent_str(agent);
367 if (agent_str.find(kFirefoxPattern) != std::string::npos) {
368 return UA_FIREFOX;
369 } else if (agent_str.find(kInternetExplorerPattern) != std::string::npos) {
370 return UA_INTERNETEXPLORER;
371 } else if (agent_str.empty()) {
372 return UA_UNKNOWN;
373 }
374 }
375 return UA_OTHER;
376 }
377
378 bool EndsWith(const std::string& a, const std::string& b) {
379 if (b.size() > a.size()) {
380 return false;
381 }
382 int result = a.compare(a.size() - b.size(), b.size(), b);
383 return result == 0;
384 }
385
386 bool GetFirefoxProfilePath(Pathname* path) {
387 #if defined(WEBRTC_WIN)
388 wchar_t w_path[MAX_PATH];
389 if (SHGetFolderPath(0, CSIDL_APPDATA, 0, SHGFP_TYPE_CURRENT, w_path) !=
390 S_OK) {
391 LOG(LS_ERROR) << "SHGetFolderPath failed";
392 return false;
393 }
394 path->SetFolder(ToUtf8(w_path, wcslen(w_path)));
395 path->AppendFolder("Mozilla");
396 path->AppendFolder("Firefox");
397 #elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
398 rtc::UnixFilesystem filesystem;
399 filesystem.SetApplicationName("Firefox");
400 bool result = filesystem.GetAppDataFolder(path, true);
401 return result;
402 #else
403 char* user_home = getenv("HOME");
404 if (user_home == NULL) {
405 return false;
406 }
407 path->SetFolder(std::string(user_home));
408 path->AppendFolder(".mozilla");
409 path->AppendFolder("firefox");
410 #endif // WEBRTC_WIN
411 return true;
412 }
413
414 bool GetDefaultFirefoxProfile(Pathname* profile_path) {
415 RTC_DCHECK(NULL != profile_path);
416 Pathname path;
417 if (!GetFirefoxProfilePath(&path)) {
418 return false;
419 }
420
421 #if USE_FIREFOX_PROFILES_INI
422 // [Profile0]
423 // Name=default
424 // IsRelative=1
425 // Path=Profiles/2de53ejb.default
426 // Default=1
427
428 // Note: we are looking for the first entry with "Default=1", or the last
429 // entry in the file
430 path.SetFilename("profiles.ini");
431 std::unique_ptr<FileStream> fs(Filesystem::OpenFile(path, "r"));
432 if (!fs) {
433 return false;
434 }
435 Pathname candidate;
436 bool relative = true;
437 std::string line;
438 while (fs->ReadLine(&line) == SR_SUCCESS) {
439 if (line.length() == 0) {
440 continue;
441 }
442 if (line.at(0) == '[') {
443 relative = true;
444 candidate.clear();
445 } else if (line.find("IsRelative=") == 0 &&
446 line.length() >= 12) {
447 // TODO: The initial Linux public launch revealed a fairly
448 // high number of machines where IsRelative= did not have anything after
449 // it. Perhaps that is legal profiles.ini syntax?
450 relative = (line.at(11) != '0');
451 } else if (line.find("Path=") == 0 &&
452 line.length() >= 6) {
453 if (relative) {
454 candidate = path;
455 } else {
456 candidate.clear();
457 }
458 candidate.AppendFolder(line.substr(5));
459 } else if (line.find("Default=") == 0 &&
460 line.length() >= 9) {
461 if ((line.at(8) != '0') && !candidate.empty()) {
462 break;
463 }
464 }
465 }
466 fs->Close();
467 if (candidate.empty()) {
468 return false;
469 }
470 profile_path->SetPathname(candidate.pathname());
471
472 #else // !USE_FIREFOX_PROFILES_INI
473 path.AppendFolder("Profiles");
474 DirectoryIterator* it = Filesystem::IterateDirectory();
475 it->Iterate(path);
476 std::string extension(".default");
477 while (!EndsWith(it->Name(), extension)) {
478 if (!it->Next()) {
479 return false;
480 }
481 }
482
483 profile_path->SetPathname(path);
484 profile->AppendFolder("Profiles");
485 profile->AppendFolder(it->Name());
486 delete it;
487
488 #endif // !USE_FIREFOX_PROFILES_INI
489
490 return true;
491 }
492
493 bool ReadFirefoxPrefs(const Pathname& filename,
494 const char * prefix,
495 StringMap* settings) {
496 std::unique_ptr<FileStream> fs(Filesystem::OpenFile(filename, "r"));
497 if (!fs) {
498 LOG(LS_ERROR) << "Failed to open file: " << filename.pathname();
499 return false;
500 }
501
502 std::string line;
503 while (fs->ReadLine(&line) == SR_SUCCESS) {
504 size_t prefix_len = strlen(prefix);
505
506 // Skip blank lines and too long lines.
507 if ((line.length() == 0) || (line.length() > kMaxLineLength)
508 || (line.at(0) == '#') || line.compare(0, 2, "/*") == 0
509 || line.compare(0, 2, " *") == 0) {
510 continue;
511 }
512
513 char buffer[kMaxLineLength];
514 strcpyn(buffer, sizeof(buffer), line.c_str());
515 int nstart = 0, nend = 0, vstart = 0, vend = 0;
516 sscanf(buffer, "user_pref(\"%n%*[^\"]%n\", %n%*[^)]%n);",
517 &nstart, &nend, &vstart, &vend);
518 if (vend > 0) {
519 char* name = buffer + nstart;
520 name[nend - nstart] = 0;
521 if ((vend - vstart >= 2) && (buffer[vstart] == '"')) {
522 vstart += 1;
523 vend -= 1;
524 }
525 char* value = buffer + vstart;
526 value[vend - vstart] = 0;
527 if ((strncmp(name, prefix, prefix_len) == 0) && *value) {
528 settings->Add(name + prefix_len, value);
529 }
530 } else {
531 LOG_F(LS_WARNING) << "Unparsed pref [" << buffer << "]";
532 }
533 }
534 fs->Close();
535 return true;
536 }
537
538 bool GetFirefoxProxySettings(const char* url, ProxyInfo* proxy) {
539 Url<char> purl(url);
540 Pathname path;
541 bool success = false;
542 if (GetDefaultFirefoxProfile(&path)) {
543 StringMap settings;
544 path.SetFilename("prefs.js");
545 if (ReadFirefoxPrefs(path, "network.proxy.", &settings)) {
546 success = true;
547 proxy->bypass_list =
548 settings.Get("no_proxies_on", "localhost, 127.0.0.1");
549 if (settings.Get("type") == "1") {
550 // User has manually specified a proxy, try to figure out what
551 // type it is.
552 if (ProxyListMatch(purl, proxy->bypass_list.c_str(), ',')) {
553 // Our url is in the list of url's to bypass proxy.
554 } else if (settings.Get("share_proxy_settings") == "true") {
555 proxy->type = PROXY_UNKNOWN;
556 proxy->address.SetIP(settings.Get("http"));
557 proxy->address.SetPort(atoi(settings.Get("http_port").c_str()));
558 } else if (settings.IsSet("socks")) {
559 proxy->type = PROXY_SOCKS5;
560 proxy->address.SetIP(settings.Get("socks"));
561 proxy->address.SetPort(atoi(settings.Get("socks_port").c_str()));
562 } else if (settings.IsSet("ssl")) {
563 proxy->type = PROXY_HTTPS;
564 proxy->address.SetIP(settings.Get("ssl"));
565 proxy->address.SetPort(atoi(settings.Get("ssl_port").c_str()));
566 } else if (settings.IsSet("http")) {
567 proxy->type = PROXY_HTTPS;
568 proxy->address.SetIP(settings.Get("http"));
569 proxy->address.SetPort(atoi(settings.Get("http_port").c_str()));
570 }
571 } else if (settings.Get("type") == "2") {
572 // Browser is configured to get proxy settings from a given url.
573 proxy->autoconfig_url = settings.Get("autoconfig_url").c_str();
574 } else if (settings.Get("type") == "4") {
575 // Browser is configured to auto detect proxy config.
576 proxy->autodetect = true;
577 } else {
578 // No proxy set.
579 }
580 }
581 }
582 return success;
583 }
584
585 #if defined(WEBRTC_WIN) // Windows specific implementation for reading Internet
586 // Explorer proxy settings.
587
588 void LogGetProxyFault() {
589 LOG_GLEM(LERROR, WINHTTP) << "WinHttpGetProxyForUrl faulted!!";
590 }
591
592 BOOL MyWinHttpGetProxyForUrl(pfnWinHttpGetProxyForUrl pWHGPFU,
593 HINTERNET hWinHttp, LPCWSTR url,
594 WINHTTP_AUTOPROXY_OPTIONS *options,
595 WINHTTP_PROXY_INFO *info) {
596 // WinHttpGetProxyForUrl() can call plugins which can crash.
597 // In the case of McAfee scriptproxy.dll, it does crash in
598 // older versions. Try to catch crashes here and treat as an
599 // error.
600 BOOL success = FALSE;
601
602 #if (_HAS_EXCEPTIONS == 0)
603 __try {
604 success = pWHGPFU(hWinHttp, url, options, info);
605 } __except(EXCEPTION_EXECUTE_HANDLER) {
606 // This is a separate function to avoid
607 // Visual C++ error 2712 when compiling with C++ EH
608 LogGetProxyFault();
609 }
610 #else
611 success = pWHGPFU(hWinHttp, url, options, info);
612 #endif // (_HAS_EXCEPTIONS == 0)
613
614 return success;
615 }
616
617 bool IsDefaultBrowserFirefox() {
618 HKEY key;
619 LONG result = RegOpenKeyEx(HKEY_CLASSES_ROOT, L"http\\shell\\open\\command",
620 0, KEY_READ, &key);
621 if (ERROR_SUCCESS != result)
622 return false;
623
624 DWORD size, type;
625 bool success = false;
626 result = RegQueryValueEx(key, L"", 0, &type, NULL, &size);
627 if (result == ERROR_SUCCESS && type == REG_SZ) {
628 wchar_t* value = new wchar_t[size+1];
629 BYTE* buffer = reinterpret_cast<BYTE*>(value);
630 result = RegQueryValueEx(key, L"", 0, &type, buffer, &size);
631 if (result == ERROR_SUCCESS) {
632 // Size returned by RegQueryValueEx is in bytes, convert to number of
633 // wchar_t's.
634 size /= sizeof(value[0]);
635 value[size] = L'\0';
636 for (size_t i = 0; i < size; ++i) {
637 value[i] = tolowercase(value[i]);
638 }
639 success = (NULL != strstr(value, L"firefox.exe"));
640 }
641 delete[] value;
642 }
643
644 RegCloseKey(key);
645 return success;
646 }
647
648 bool GetWinHttpProxySettings(const char* url, ProxyInfo* proxy) {
649 HMODULE winhttp_handle = LoadLibrary(L"winhttp.dll");
650 if (winhttp_handle == NULL) {
651 LOG(LS_ERROR) << "Failed to load winhttp.dll.";
652 return false;
653 }
654 WINHTTP_CURRENT_USER_IE_PROXY_CONFIG iecfg;
655 memset(&iecfg, 0, sizeof(iecfg));
656 Url<char> purl(url);
657 pfnWinHttpGetIEProxyConfig pWHGIEPC =
658 reinterpret_cast<pfnWinHttpGetIEProxyConfig>(
659 GetProcAddress(winhttp_handle,
660 "WinHttpGetIEProxyConfigForCurrentUser"));
661 bool success = false;
662 if (pWHGIEPC && pWHGIEPC(&iecfg)) {
663 // We were read proxy config successfully.
664 success = true;
665 if (iecfg.fAutoDetect) {
666 proxy->autodetect = true;
667 }
668 if (iecfg.lpszAutoConfigUrl) {
669 proxy->autoconfig_url = ToUtf8(iecfg.lpszAutoConfigUrl);
670 GlobalFree(iecfg.lpszAutoConfigUrl);
671 }
672 if (iecfg.lpszProxyBypass) {
673 proxy->bypass_list = ToUtf8(iecfg.lpszProxyBypass);
674 GlobalFree(iecfg.lpszProxyBypass);
675 }
676 if (iecfg.lpszProxy) {
677 if (!ProxyListMatch(purl, proxy->bypass_list, ';')) {
678 ParseProxy(ToUtf8(iecfg.lpszProxy), proxy);
679 }
680 GlobalFree(iecfg.lpszProxy);
681 }
682 }
683 FreeLibrary(winhttp_handle);
684 return success;
685 }
686
687 // Uses the WinHTTP API to auto detect proxy for the given url. Firefox and IE
688 // have slightly different option dialogs for proxy settings. In Firefox,
689 // either a location of a proxy configuration file can be specified or auto
690 // detection can be selected. In IE theese two options can be independently
691 // selected. For the case where both options are selected (only IE) we try to
692 // fetch the config file first, and if that fails we'll perform an auto
693 // detection.
694 //
695 // Returns true if we successfully performed an auto detection not depending on
696 // whether we found a proxy or not. Returns false on error.
697 bool WinHttpAutoDetectProxyForUrl(const char* agent, const char* url,
698 ProxyInfo* proxy) {
699 Url<char> purl(url);
700 bool success = true;
701 HMODULE winhttp_handle = LoadLibrary(L"winhttp.dll");
702 if (winhttp_handle == NULL) {
703 LOG(LS_ERROR) << "Failed to load winhttp.dll.";
704 return false;
705 }
706 pfnWinHttpOpen pWHO =
707 reinterpret_cast<pfnWinHttpOpen>(GetProcAddress(winhttp_handle,
708 "WinHttpOpen"));
709 pfnWinHttpCloseHandle pWHCH =
710 reinterpret_cast<pfnWinHttpCloseHandle>(
711 GetProcAddress(winhttp_handle, "WinHttpCloseHandle"));
712 pfnWinHttpGetProxyForUrl pWHGPFU =
713 reinterpret_cast<pfnWinHttpGetProxyForUrl>(
714 GetProcAddress(winhttp_handle, "WinHttpGetProxyForUrl"));
715 if (pWHO && pWHCH && pWHGPFU) {
716 if (HINTERNET hWinHttp = pWHO(ToUtf16(agent).c_str(),
717 WINHTTP_ACCESS_TYPE_NO_PROXY,
718 WINHTTP_NO_PROXY_NAME,
719 WINHTTP_NO_PROXY_BYPASS,
720 0)) {
721 BOOL result = FALSE;
722 WINHTTP_PROXY_INFO info;
723 memset(&info, 0, sizeof(info));
724 if (proxy->autodetect) {
725 // Use DHCP and DNS to try to find any proxy to use.
726 WINHTTP_AUTOPROXY_OPTIONS options;
727 memset(&options, 0, sizeof(options));
728 options.fAutoLogonIfChallenged = TRUE;
729
730 options.dwFlags |= WINHTTP_AUTOPROXY_AUTO_DETECT;
731 options.dwAutoDetectFlags |= WINHTTP_AUTO_DETECT_TYPE_DHCP
732 | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
733 result = MyWinHttpGetProxyForUrl(
734 pWHGPFU, hWinHttp, ToUtf16(url).c_str(), &options, &info);
735 }
736 if (!result && !proxy->autoconfig_url.empty()) {
737 // We have the location of a proxy config file. Download it and
738 // execute it to find proxy settings for our url.
739 WINHTTP_AUTOPROXY_OPTIONS options;
740 memset(&options, 0, sizeof(options));
741 memset(&info, 0, sizeof(info));
742 options.fAutoLogonIfChallenged = TRUE;
743
744 std::wstring autoconfig_url16((ToUtf16)(proxy->autoconfig_url));
745 options.dwFlags |= WINHTTP_AUTOPROXY_CONFIG_URL;
746 options.lpszAutoConfigUrl = autoconfig_url16.c_str();
747
748 result = MyWinHttpGetProxyForUrl(
749 pWHGPFU, hWinHttp, ToUtf16(url).c_str(), &options, &info);
750 }
751 if (result) {
752 // Either the given auto config url was valid or auto
753 // detection found a proxy on this network.
754 if (info.lpszProxy) {
755 // TODO: Does this bypass list differ from the list
756 // retreived from GetWinHttpProxySettings earlier?
757 if (info.lpszProxyBypass) {
758 proxy->bypass_list = ToUtf8(info.lpszProxyBypass);
759 GlobalFree(info.lpszProxyBypass);
760 } else {
761 proxy->bypass_list.clear();
762 }
763 if (!ProxyListMatch(purl, proxy->bypass_list, ';')) {
764 // Found proxy for this URL. If parsing the address turns
765 // out ok then we are successful.
766 success = ParseProxy(ToUtf8(info.lpszProxy), proxy);
767 }
768 GlobalFree(info.lpszProxy);
769 }
770 } else {
771 // We could not find any proxy for this url.
772 LOG(LS_INFO) << "No proxy detected for " << url;
773 }
774 pWHCH(hWinHttp);
775 }
776 } else {
777 LOG(LS_ERROR) << "Failed loading WinHTTP functions.";
778 success = false;
779 }
780 FreeLibrary(winhttp_handle);
781 return success;
782 }
783
784 #if 0 // Below functions currently not used.
785
786 bool GetJsProxySettings(const char* url, ProxyInfo* proxy) {
787 Url<char> purl(url);
788 bool success = false;
789
790 if (HMODULE hModJS = LoadLibrary(_T("jsproxy.dll"))) {
791 pfnInternetGetProxyInfo pIGPI =
792 reinterpret_cast<pfnInternetGetProxyInfo>(
793 GetProcAddress(hModJS, "InternetGetProxyInfo"));
794 if (pIGPI) {
795 char proxy[256], host[256];
796 memset(proxy, 0, sizeof(proxy));
797 char * ptr = proxy;
798 DWORD proxylen = sizeof(proxy);
799 std::string surl = Utf8String(url);
800 DWORD hostlen = _snprintf(host, sizeof(host), "http%s://%S",
801 purl.secure() ? "s" : "", purl.server());
802 if (pIGPI(surl.data(), surl.size(), host, hostlen, &ptr, &proxylen)) {
803 LOG(INFO) << "Proxy: " << proxy;
804 } else {
805 LOG_GLE(INFO) << "InternetGetProxyInfo";
806 }
807 }
808 FreeLibrary(hModJS);
809 }
810 return success;
811 }
812
813 bool GetWmProxySettings(const char* url, ProxyInfo* proxy) {
814 Url<char> purl(url);
815 bool success = false;
816
817 INSNetSourceCreator * nsc = 0;
818 HRESULT hr = CoCreateInstance(CLSID_ClientNetManager, 0, CLSCTX_ALL,
819 IID_INSNetSourceCreator, (LPVOID *) &nsc);
820 if (SUCCEEDED(hr)) {
821 if (SUCCEEDED(hr = nsc->Initialize())) {
822 VARIANT dispatch;
823 VariantInit(&dispatch);
824 if (SUCCEEDED(hr = nsc->GetNetSourceAdminInterface(L"http", &dispatch))) {
825 IWMSInternalAdminNetSource * ians = 0;
826 if (SUCCEEDED(hr = dispatch.pdispVal->QueryInterface(
827 IID_IWMSInternalAdminNetSource, (LPVOID *) &ians))) {
828 _bstr_t host(purl.server());
829 BSTR proxy = 0;
830 BOOL bProxyEnabled = FALSE;
831 DWORD port, context = 0;
832 if (SUCCEEDED(hr = ians->FindProxyForURL(
833 L"http", host, &bProxyEnabled, &proxy, &port, &context))) {
834 success = true;
835 if (bProxyEnabled) {
836 _bstr_t sproxy = proxy;
837 proxy->ptype = PT_HTTPS;
838 proxy->host = sproxy;
839 proxy->port = port;
840 }
841 }
842 SysFreeString(proxy);
843 if (FAILED(hr = ians->ShutdownProxyContext(context))) {
844 LOG(LS_INFO) << "IWMSInternalAdminNetSource::ShutdownProxyContext"
845 << "failed: " << hr;
846 }
847 ians->Release();
848 }
849 }
850 VariantClear(&dispatch);
851 if (FAILED(hr = nsc->Shutdown())) {
852 LOG(LS_INFO) << "INSNetSourceCreator::Shutdown failed: " << hr;
853 }
854 }
855 nsc->Release();
856 }
857 return success;
858 }
859
860 bool GetIePerConnectionProxySettings(const char* url, ProxyInfo* proxy) {
861 Url<char> purl(url);
862 bool success = false;
863
864 INTERNET_PER_CONN_OPTION_LIST list;
865 INTERNET_PER_CONN_OPTION options[3];
866 memset(&list, 0, sizeof(list));
867 memset(&options, 0, sizeof(options));
868
869 list.dwSize = sizeof(list);
870 list.dwOptionCount = 3;
871 list.pOptions = options;
872 options[0].dwOption = INTERNET_PER_CONN_FLAGS;
873 options[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
874 options[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS;
875 DWORD dwSize = sizeof(list);
876
877 if (!InternetQueryOption(0, INTERNET_OPTION_PER_CONNECTION_OPTION, &list,
878 &dwSize)) {
879 LOG(LS_INFO) << "InternetQueryOption failed: " << GetLastError();
880 } else if ((options[0].Value.dwValue & PROXY_TYPE_PROXY) != 0) {
881 success = true;
882 if (!ProxyListMatch(purl, nonnull(options[2].Value.pszValue), _T(';'))) {
883 ParseProxy(nonnull(options[1].Value.pszValue), proxy);
884 }
885 } else if ((options[0].Value.dwValue & PROXY_TYPE_DIRECT) != 0) {
886 success = true;
887 } else {
888 LOG(LS_INFO) << "unknown internet access type: "
889 << options[0].Value.dwValue;
890 }
891 if (options[1].Value.pszValue) {
892 GlobalFree(options[1].Value.pszValue);
893 }
894 if (options[2].Value.pszValue) {
895 GlobalFree(options[2].Value.pszValue);
896 }
897 return success;
898 }
899
900 #endif // 0
901
902 // Uses the InternetQueryOption function to retrieve proxy settings
903 // from the registry. This will only give us the 'static' settings,
904 // ie, not any information about auto config etc.
905 bool GetIeLanProxySettings(const char* url, ProxyInfo* proxy) {
906 Url<char> purl(url);
907 bool success = false;
908
909 wchar_t buffer[1024];
910 memset(buffer, 0, sizeof(buffer));
911 INTERNET_PROXY_INFO * info = reinterpret_cast<INTERNET_PROXY_INFO *>(buffer);
912 DWORD dwSize = sizeof(buffer);
913
914 if (!InternetQueryOption(0, INTERNET_OPTION_PROXY, info, &dwSize)) {
915 LOG(LS_INFO) << "InternetQueryOption failed: " << GetLastError();
916 } else if (info->dwAccessType == INTERNET_OPEN_TYPE_DIRECT) {
917 success = true;
918 } else if (info->dwAccessType == INTERNET_OPEN_TYPE_PROXY) {
919 success = true;
920 if (!ProxyListMatch(purl, nonnull(reinterpret_cast<const char*>(
921 info->lpszProxyBypass)), ' ')) {
922 ParseProxy(nonnull(reinterpret_cast<const char*>(info->lpszProxy)),
923 proxy);
924 }
925 } else {
926 LOG(LS_INFO) << "unknown internet access type: " << info->dwAccessType;
927 }
928 return success;
929 }
930
931 bool GetIeProxySettings(const char* agent, const char* url, ProxyInfo* proxy) {
932 bool success = GetWinHttpProxySettings(url, proxy);
933 if (!success) {
934 // TODO: Should always call this if no proxy were detected by
935 // GetWinHttpProxySettings?
936 // WinHttp failed. Try using the InternetOptionQuery method instead.
937 return GetIeLanProxySettings(url, proxy);
938 }
939 return true;
940 }
941
942 #endif // WEBRTC_WIN
943
944 #if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) // WEBRTC_MAC && !defined(WEBRT C_IOS) specific implementation for reading system wide
945 // proxy settings.
946
947 bool p_getProxyInfoForTypeFromDictWithKeys(ProxyInfo* proxy,
948 ProxyType type,
949 const CFDictionaryRef proxyDict,
950 const CFStringRef enabledKey,
951 const CFStringRef hostKey,
952 const CFStringRef portKey) {
953 // whether or not we set up the proxy info.
954 bool result = false;
955
956 // we use this as a scratch variable for determining if operations
957 // succeeded.
958 bool converted = false;
959
960 // the data we need to construct the SocketAddress for the proxy.
961 std::string hostname;
962 int port;
963
964 if ((proxyDict != NULL) &&
965 (CFGetTypeID(proxyDict) == CFDictionaryGetTypeID())) {
966 // CoreFoundation stuff that we'll have to get from
967 // the dictionaries and interpret or convert into more usable formats.
968 CFNumberRef enabledCFNum;
969 CFNumberRef portCFNum;
970 CFStringRef hostCFStr;
971
972 enabledCFNum = (CFNumberRef)CFDictionaryGetValue(proxyDict, enabledKey);
973
974 if (p_isCFNumberTrue(enabledCFNum)) {
975 // let's see if we can get the address and port.
976 hostCFStr = (CFStringRef)CFDictionaryGetValue(proxyDict, hostKey);
977 converted = p_convertHostCFStringRefToCPPString(hostCFStr, hostname);
978 if (converted) {
979 portCFNum = (CFNumberRef)CFDictionaryGetValue(proxyDict, portKey);
980 converted = p_convertCFNumberToInt(portCFNum, &port);
981 if (converted) {
982 // we have something enabled, with a hostname and a port.
983 // That's sufficient to set up the proxy info.
984 proxy->type = type;
985 proxy->address.SetIP(hostname);
986 proxy->address.SetPort(port);
987 result = true;
988 }
989 }
990 }
991 }
992
993 return result;
994 }
995
996 // Looks for proxy information in the given dictionary,
997 // return true if it found sufficient information to define one,
998 // false otherwise. This is guaranteed to not change the values in proxy
999 // unless a full-fledged proxy description was discovered in the dictionary.
1000 // However, at the present time this does not support username or password.
1001 // Checks first for a SOCKS proxy, then for HTTPS, then HTTP.
1002 bool GetMacProxySettingsFromDictionary(ProxyInfo* proxy,
1003 const CFDictionaryRef proxyDict) {
1004 // the function result.
1005 bool gotProxy = false;
1006
1007
1008 // first we see if there's a SOCKS proxy in place.
1009 gotProxy = p_getProxyInfoForTypeFromDictWithKeys(proxy,
1010 PROXY_SOCKS5,
1011 proxyDict,
1012 kSCPropNetProxiesSOCKSEnable,
1013 kSCPropNetProxiesSOCKSProxy,
1014 kSCPropNetProxiesSOCKSPort);
1015
1016 if (!gotProxy) {
1017 // okay, no SOCKS proxy, let's look for https.
1018 gotProxy = p_getProxyInfoForTypeFromDictWithKeys(proxy,
1019 PROXY_HTTPS,
1020 proxyDict,
1021 kSCPropNetProxiesHTTPSEnable,
1022 kSCPropNetProxiesHTTPSProxy,
1023 kSCPropNetProxiesHTTPSPort);
1024 if (!gotProxy) {
1025 // Finally, try HTTP proxy. Note that flute doesn't
1026 // differentiate between HTTPS and HTTP, hence we are using the
1027 // same flute type here, ie. PROXY_HTTPS.
1028 gotProxy = p_getProxyInfoForTypeFromDictWithKeys(
1029 proxy, PROXY_HTTPS, proxyDict, kSCPropNetProxiesHTTPEnable,
1030 kSCPropNetProxiesHTTPProxy, kSCPropNetProxiesHTTPPort);
1031 }
1032 }
1033 return gotProxy;
1034 }
1035
1036 // TODO(hughv) Update keychain functions. They work on 10.8, but are depricated.
1037 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1038 bool p_putPasswordInProxyInfo(ProxyInfo* proxy) {
1039 bool result = true; // by default we assume we're good.
1040 // for all we know there isn't any password. We'll set to false
1041 // if we find a problem.
1042
1043 // Ask the keychain for an internet password search for the given protocol.
1044 OSStatus oss = 0;
1045 SecKeychainAttributeList attrList;
1046 attrList.count = 3;
1047 SecKeychainAttribute attributes[3];
1048 attrList.attr = attributes;
1049
1050 attributes[0].tag = kSecProtocolItemAttr;
1051 attributes[0].length = sizeof(SecProtocolType);
1052 SecProtocolType protocol;
1053 switch (proxy->type) {
1054 case PROXY_HTTPS :
1055 protocol = kSecProtocolTypeHTTPS;
1056 break;
1057 case PROXY_SOCKS5 :
1058 protocol = kSecProtocolTypeSOCKS;
1059 break;
1060 default :
1061 LOG(LS_ERROR) << "asked for proxy password for unknown proxy type.";
1062 result = false;
1063 break;
1064 }
1065 attributes[0].data = &protocol;
1066
1067 UInt32 port = proxy->address.port();
1068 attributes[1].tag = kSecPortItemAttr;
1069 attributes[1].length = sizeof(UInt32);
1070 attributes[1].data = &port;
1071
1072 std::string ip = proxy->address.ipaddr().ToString();
1073 attributes[2].tag = kSecServerItemAttr;
1074 attributes[2].length = ip.length();
1075 attributes[2].data = const_cast<char*>(ip.c_str());
1076
1077 if (result) {
1078 LOG(LS_INFO) << "trying to get proxy username/password";
1079 SecKeychainSearchRef sref;
1080 oss = SecKeychainSearchCreateFromAttributes(NULL,
1081 kSecInternetPasswordItemClass,
1082 &attrList, &sref);
1083 if (0 == oss) {
1084 LOG(LS_INFO) << "SecKeychainSearchCreateFromAttributes was good";
1085 // Get the first item, if there is one.
1086 SecKeychainItemRef iref;
1087 oss = SecKeychainSearchCopyNext(sref, &iref);
1088 if (0 == oss) {
1089 LOG(LS_INFO) << "...looks like we have the username/password data";
1090 // If there is, get the username and the password.
1091
1092 SecKeychainAttributeInfo attribsToGet;
1093 attribsToGet.count = 1;
1094 UInt32 tag = kSecAccountItemAttr;
1095 UInt32 format = CSSM_DB_ATTRIBUTE_FORMAT_STRING;
1096 void *data;
1097 UInt32 length;
1098 SecKeychainAttributeList *localList;
1099
1100 attribsToGet.tag = &tag;
1101 attribsToGet.format = &format;
1102 OSStatus copyres = SecKeychainItemCopyAttributesAndData(iref,
1103 &attribsToGet,
1104 NULL,
1105 &localList,
1106 &length,
1107 &data);
1108 if (0 == copyres) {
1109 LOG(LS_INFO) << "...and we can pull it out.";
1110 // now, we know from experimentation (sadly not from docs)
1111 // that the username is in the local attribute list,
1112 // and the password in the data,
1113 // both without null termination but with info on their length.
1114 // grab the password from the data.
1115 std::string password;
1116 password.append(static_cast<const char*>(data), length);
1117
1118 // make the password into a CryptString
1119 // huh, at the time of writing, you can't.
1120 // so we'll skip that for now and come back to it later.
1121
1122 // now put the username in the proxy.
1123 if (1 <= localList->attr->length) {
1124 proxy->username.append(
1125 static_cast<const char*>(localList->attr->data),
1126 localList->attr->length);
1127 LOG(LS_INFO) << "username is " << proxy->username;
1128 } else {
1129 LOG(LS_ERROR) << "got keychain entry with no username";
1130 result = false;
1131 }
1132 } else {
1133 LOG(LS_ERROR) << "couldn't copy info from keychain.";
1134 result = false;
1135 }
1136 SecKeychainItemFreeAttributesAndData(localList, data);
1137 } else if (errSecItemNotFound == oss) {
1138 LOG(LS_INFO) << "...username/password info not found";
1139 } else {
1140 // oooh, neither 0 nor itemNotFound.
1141 LOG(LS_ERROR) << "Couldn't get keychain information, error code" << oss;
1142 result = false;
1143 }
1144 } else if (errSecItemNotFound == oss) { // noop
1145 } else {
1146 // oooh, neither 0 nor itemNotFound.
1147 LOG(LS_ERROR) << "Couldn't get keychain information, error code" << oss;
1148 result = false;
1149 }
1150 }
1151
1152 return result;
1153 }
1154
1155 bool GetMacProxySettings(ProxyInfo* proxy) {
1156 // based on the Apple Technical Q&A QA1234
1157 // http://developer.apple.com/qa/qa2001/qa1234.html
1158 CFDictionaryRef proxyDict = SCDynamicStoreCopyProxies(NULL);
1159 bool result = false;
1160
1161 if (proxyDict != NULL) {
1162 // sending it off to another function makes it easier to unit test
1163 // since we can make our own dictionary to hand to that function.
1164 result = GetMacProxySettingsFromDictionary(proxy, proxyDict);
1165
1166 if (result) {
1167 result = p_putPasswordInProxyInfo(proxy);
1168 }
1169
1170 CFRelease(proxyDict);
1171 } else {
1172 LOG(LS_ERROR) << "SCDynamicStoreCopyProxies failed";
1173 }
1174
1175 return result;
1176 }
1177 #endif // WEBRTC_MAC && !defined(WEBRTC_IOS)
1178
1179 #ifdef WEBRTC_IOS
1180 // iOS has only http proxy
1181 bool GetiOSProxySettings(ProxyInfo* proxy) {
1182
1183 bool result = false;
1184
1185 CFDictionaryRef proxy_dict = CFNetworkCopySystemProxySettings();
1186 if (!proxy_dict) {
1187 LOG(LS_ERROR) << "CFNetworkCopySystemProxySettings failed";
1188 return false;
1189 }
1190
1191 CFNumberRef proxiesHTTPEnable = (CFNumberRef)CFDictionaryGetValue(
1192 proxy_dict, kCFNetworkProxiesHTTPEnable);
1193 if (!p_isCFNumberTrue(proxiesHTTPEnable)) {
1194 CFRelease(proxy_dict);
1195 return false;
1196 }
1197
1198 CFStringRef proxy_address = (CFStringRef)CFDictionaryGetValue(
1199 proxy_dict, kCFNetworkProxiesHTTPProxy);
1200 CFNumberRef proxy_port = (CFNumberRef)CFDictionaryGetValue(
1201 proxy_dict, kCFNetworkProxiesHTTPPort);
1202
1203 // the data we need to construct the SocketAddress for the proxy.
1204 std::string hostname;
1205 int port;
1206 if (p_convertHostCFStringRefToCPPString(proxy_address, hostname) &&
1207 p_convertCFNumberToInt(proxy_port, &port)) {
1208 // We have something enabled, with a hostname and a port.
1209 // That's sufficient to set up the proxy info.
1210 // Finally, try HTTP proxy. Note that flute doesn't
1211 // differentiate between HTTPS and HTTP, hence we are using the
1212 // same flute type here, ie. PROXY_HTTPS.
1213 proxy->type = PROXY_HTTPS;
1214
1215 proxy->address.SetIP(hostname);
1216 proxy->address.SetPort(port);
1217 result = true;
1218 }
1219
1220 CFRelease(proxy_dict);
1221
1222 return result;
1223 }
1224 #endif // WEBRTC_IOS
1225
1226 bool AutoDetectProxySettings(const char* agent, const char* url,
1227 ProxyInfo* proxy) {
1228 #if defined(WEBRTC_WIN)
1229 return WinHttpAutoDetectProxyForUrl(agent, url, proxy);
1230 #else
1231 LOG(LS_WARNING) << "Proxy auto-detection not implemented for this platform";
1232 return false;
1233 #endif
1234 }
1235
1236 bool GetSystemDefaultProxySettings(const char* agent, const char* url,
1237 ProxyInfo* proxy) {
1238 #if defined(WEBRTC_WIN)
1239 return GetIeProxySettings(agent, url, proxy);
1240 #elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
1241 return GetMacProxySettings(proxy);
1242 #elif defined(WEBRTC_IOS)
1243 return GetiOSProxySettings(proxy);
1244 #else
1245 // TODO: Get System settings if browser is not firefox.
1246 return GetFirefoxProxySettings(url, proxy);
1247 #endif
1248 }
1249
1250 bool GetProxySettingsForUrl(const char* agent, const char* url,
1251 ProxyInfo* proxy, bool long_operation) {
1252 UserAgent a = GetAgent(agent);
1253 bool result;
1254 switch (a) {
1255 case UA_FIREFOX: {
1256 result = GetFirefoxProxySettings(url, proxy);
1257 break;
1258 }
1259 #if defined(WEBRTC_WIN)
1260 case UA_INTERNETEXPLORER:
1261 result = GetIeProxySettings(agent, url, proxy);
1262 break;
1263 case UA_UNKNOWN:
1264 // Agent not defined, check default browser.
1265 if (IsDefaultBrowserFirefox()) {
1266 result = GetFirefoxProxySettings(url, proxy);
1267 } else {
1268 result = GetIeProxySettings(agent, url, proxy);
1269 }
1270 break;
1271 #endif // WEBRTC_WIN
1272 default:
1273 result = GetSystemDefaultProxySettings(agent, url, proxy);
1274 break;
1275 }
1276
1277 // TODO: Consider using the 'long_operation' parameter to
1278 // decide whether to do the auto detection.
1279 if (result && (proxy->autodetect ||
1280 !proxy->autoconfig_url.empty())) {
1281 // Use WinHTTP to auto detect proxy for us.
1282 result = AutoDetectProxySettings(agent, url, proxy);
1283 if (!result) {
1284 // Either auto detection is not supported or we simply didn't
1285 // find any proxy, reset type.
1286 proxy->type = rtc::PROXY_NONE;
1287 }
1288 }
1289 return result;
1290 }
1291
1292 } // namespace rtc
OLDNEW
« no previous file with comments | « webrtc/base/proxydetect.h ('k') | webrtc/base/proxydetect_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698