147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/*
247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *
447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Use of this source code is governed by a BSD-style license
547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  that can be found in the LICENSE file in the root of the source
647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  tree. An additional intellectual property rights grant can be found
747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  in the file PATENTS.  All contributing project authors may
847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org */
1047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/proxydetect.h"
1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN)
1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/win32.h"
1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <shlobj.h>
1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif  // WEBRTC_WIN
1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#ifdef HAVE_CONFIG_H
1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "config.h"
2047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif
2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
2347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <SystemConfiguration/SystemConfiguration.h>
2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <CoreFoundation/CoreFoundation.h>
2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <CoreServices/CoreServices.h>
2647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <Security/Security.h>
2747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "macconversion.h"
2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif
2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <map>
3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/fileutils.h"
3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/httpcommon.h"
3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/httpcommon-inl.h"
3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/pathutils.h"
3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/stringutils.h"
3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN)
3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define _TRY_WINHTTP 1
4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define _TRY_JSPROXY 0
4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define _TRY_WM_FINDPROXY 0
4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define _TRY_IE_LAN_SETTINGS 1
4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif  // WEBRTC_WIN
4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// For all platforms try Firefox.
4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define _TRY_FIREFOX 1
4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Use profiles.ini to find the correct profile for this user.
4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// If not set, we'll just look for the default one.
5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define USE_FIREFOX_PROFILES_INI 1
5147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
5247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic const size_t kMaxLineLength = 1024;
5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic const char kFirefoxPattern[] = "Firefox";
5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstatic const char kInternetExplorerPattern[] = "MSIE";
5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstruct StringMap {
5747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public:
5847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void Add(const char * name, const char * value) { map_[name] = value; }
5947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const std::string& Get(const char * name, const char * def = "") const {
6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    std::map<std::string, std::string>::const_iterator it =
6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        map_.find(name);
6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (it != map_.end())
6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return it->second;
6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    def_ = def;
6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return def_;
6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool IsSet(const char * name) const {
6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return (map_.find(name) != map_.end());
6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org private:
7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::map<std::string, std::string> map_;
7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  mutable std::string def_;
7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgenum UserAgent {
7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  UA_FIREFOX,
7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  UA_INTERNETEXPLORER,
7847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  UA_OTHER,
7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  UA_UNKNOWN
8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if _TRY_WINHTTP
8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//#include <winhttp.h>
8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Note: From winhttp.h
8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgconst char WINHTTP[] = "winhttp";
8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
8847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtypedef LPVOID HINTERNET;
8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
9047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtypedef struct {
9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DWORD  dwAccessType;      // see WINHTTP_ACCESS_* types below
9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LPWSTR lpszProxy;         // proxy server list
9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LPWSTR lpszProxyBypass;   // proxy bypass list
9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} WINHTTP_PROXY_INFO, * LPWINHTTP_PROXY_INFO;
9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtypedef struct {
9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DWORD   dwFlags;
9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DWORD   dwAutoDetectFlags;
9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LPCWSTR lpszAutoConfigUrl;
10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LPVOID  lpvReserved;
10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DWORD   dwReserved;
10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  BOOL    fAutoLogonIfChallenged;
10347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} WINHTTP_AUTOPROXY_OPTIONS;
10447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
10547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtypedef struct {
10647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  BOOL    fAutoDetect;
10747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LPWSTR  lpszAutoConfigUrl;
10847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LPWSTR  lpszProxy;
10947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LPWSTR  lpszProxyBypass;
11047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} WINHTTP_CURRENT_USER_IE_PROXY_CONFIG;
11147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
11247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgextern "C" {
11347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  typedef HINTERNET (WINAPI * pfnWinHttpOpen)
11447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      (
11547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          IN LPCWSTR pwszUserAgent,
11647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          IN DWORD   dwAccessType,
11747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          IN LPCWSTR pwszProxyName   OPTIONAL,
11847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          IN LPCWSTR pwszProxyBypass OPTIONAL,
11947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          IN DWORD   dwFlags
12047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          );
12147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  typedef BOOL (STDAPICALLTYPE * pfnWinHttpCloseHandle)
12247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      (
12347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          IN HINTERNET hInternet
12447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          );
12547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  typedef BOOL (STDAPICALLTYPE * pfnWinHttpGetProxyForUrl)
12647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      (
12747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          IN  HINTERNET                   hSession,
12847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          IN  LPCWSTR                     lpcwszUrl,
12947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          IN  WINHTTP_AUTOPROXY_OPTIONS * pAutoProxyOptions,
13047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          OUT WINHTTP_PROXY_INFO *        pProxyInfo
13147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          );
13247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  typedef BOOL (STDAPICALLTYPE * pfnWinHttpGetIEProxyConfig)
13347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      (
13447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          IN OUT WINHTTP_CURRENT_USER_IE_PROXY_CONFIG * pProxyConfig
13547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          );
13647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
13747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} // extern "C"
13847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
13947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WINHTTP_AUTOPROXY_AUTO_DETECT           0x00000001
14047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WINHTTP_AUTOPROXY_CONFIG_URL            0x00000002
14147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WINHTTP_AUTOPROXY_RUN_INPROCESS         0x00010000
14247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WINHTTP_AUTOPROXY_RUN_OUTPROCESS_ONLY   0x00020000
14347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WINHTTP_AUTO_DETECT_TYPE_DHCP           0x00000001
14447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WINHTTP_AUTO_DETECT_TYPE_DNS_A          0x00000002
14547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WINHTTP_ACCESS_TYPE_DEFAULT_PROXY               0
14647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WINHTTP_ACCESS_TYPE_NO_PROXY                    1
14747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WINHTTP_ACCESS_TYPE_NAMED_PROXY                 3
14847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WINHTTP_NO_PROXY_NAME     NULL
14947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WINHTTP_NO_PROXY_BYPASS   NULL
15047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
15147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // _TRY_WINHTTP
15247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
15347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if _TRY_JSPROXY
15447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgextern "C" {
15547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  typedef BOOL (STDAPICALLTYPE * pfnInternetGetProxyInfo)
15647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      (
15747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          LPCSTR lpszUrl,
15847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          DWORD dwUrlLength,
15947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          LPSTR lpszUrlHostName,
16047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          DWORD dwUrlHostNameLength,
16147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          LPSTR * lplpszProxyHostName,
16247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          LPDWORD lpdwProxyHostNameLength
16347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          );
16447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org} // extern "C"
16547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // _TRY_JSPROXY
16647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
16747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if _TRY_WM_FINDPROXY
16847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <comutil.h>
16947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <wmnetsourcecreator.h>
17047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <wmsinternaladminnetsource.h>
17147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // _TRY_WM_FINDPROXY
17247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
17347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if _TRY_IE_LAN_SETTINGS
17447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <wininet.h>
17547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <string>
17647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // _TRY_IE_LAN_SETTINGS
17747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
17847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgnamespace rtc {
17947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
18047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//////////////////////////////////////////////////////////////////////
18147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Utility Functions
18247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//////////////////////////////////////////////////////////////////////
18347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
18447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN)
18547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#ifdef _UNICODE
18647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
18747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtypedef std::wstring tstring;
18847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstd::string Utf8String(const tstring& str) { return ToUtf8(str); }
18947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
19047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#else  // !_UNICODE
19147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
19247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgtypedef std::string tstring;
19347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgstd::string Utf8String(const tstring& str) { return str; }
19447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
19547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif  // !_UNICODE
19647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif  // WEBRTC_WIN
19747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
19847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool ProxyItemMatch(const Url<char>& url, char * item, size_t len) {
19947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // hostname:443
20047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (char * port = ::strchr(item, ':')) {
20147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *port++ = '\0';
20247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (url.port() != atol(port)) {
20347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return false;
20447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
20547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
20647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
20747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // A.B.C.D or A.B.C.D/24
20847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int a, b, c, d, m;
20947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int match = sscanf(item, "%d.%d.%d.%d/%d", &a, &b, &c, &d, &m);
21047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (match >= 4) {
21147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    uint32 ip = ((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) |
21247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        (d & 0xFF);
21347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if ((match < 5) || (m > 32))
21447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      m = 32;
21547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    else if (m < 0)
21647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      m = 0;
21747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    uint32 mask = (m == 0) ? 0 : (~0UL) << (32 - m);
21847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    SocketAddress addr(url.host(), 0);
21947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // TODO: Support IPv6 proxyitems. This code block is IPv4 only anyway.
22047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return !addr.IsUnresolved() &&
22147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        ((addr.ipaddr().v4AddressAsHostOrderInteger() & mask) == (ip & mask));
22247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
22347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
22447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // .foo.com
22547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (*item == '.') {
22647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    size_t hostlen = url.host().length();
22747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return (hostlen > len)
22847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        && (stricmp(url.host().c_str() + (hostlen - len), item) == 0);
22947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
23047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
23147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // localhost or www.*.com
23247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!string_match(url.host().c_str(), item))
23347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
23447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
23547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
23647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
23747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
23847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool ProxyListMatch(const Url<char>& url, const std::string& proxy_list,
23947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                    char sep) {
24047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const size_t BUFSIZE = 256;
24147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  char buffer[BUFSIZE];
24247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const char* list = proxy_list.c_str();
24347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  while (*list) {
24447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // Remove leading space
24547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (isspace(*list)) {
24647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ++list;
24747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      continue;
24847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
24947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // Break on separator
25047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    size_t len;
25147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    const char * start = list;
25247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (const char * end = ::strchr(list, sep)) {
25347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      len = (end - list);
25447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      list += len + 1;
25547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    } else {
25647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      len = strlen(list);
25747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      list += len;
25847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
25947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // Remove trailing space
26047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    while ((len > 0) && isspace(start[len-1]))
26147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      --len;
26247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // Check for oversized entry
26347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (len >= BUFSIZE)
26447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      continue;
26547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    memcpy(buffer, start, len);
26647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    buffer[len] = 0;
26747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (!ProxyItemMatch(url, buffer, len))
26847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      continue;
26947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return true;
27047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
27147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return false;
27247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
27347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
27447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool Better(ProxyType lhs, const ProxyType rhs) {
27547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // PROXY_NONE, PROXY_HTTPS, PROXY_SOCKS5, PROXY_UNKNOWN
27647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const int PROXY_VALUE[5] = { 0, 2, 3, 1 };
27747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return (PROXY_VALUE[lhs] > PROXY_VALUE[rhs]);
27847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
27947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
28047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool ParseProxy(const std::string& saddress, ProxyInfo* proxy) {
28147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const size_t kMaxAddressLength = 1024;
28247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Allow semicolon, space, or tab as an address separator
28347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const char* const kAddressSeparator = " ;\t";
28447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
28547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ProxyType ptype;
28647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::string host;
28747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  uint16 port;
28847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
28947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const char* address = saddress.c_str();
29047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  while (*address) {
29147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    size_t len;
29247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    const char * start = address;
29347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (const char * sep = strchr(address, kAddressSeparator)) {
29447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      len = (sep - address);
29547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      address += len + 1;
29647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      while (*address != '\0' && ::strchr(kAddressSeparator, *address)) {
29747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        address += 1;
29847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
29947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    } else {
30047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      len = strlen(address);
30147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      address += len;
30247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
30347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
30447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (len > kMaxAddressLength - 1) {
30547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      LOG(LS_WARNING) << "Proxy address too long [" << start << "]";
30647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      continue;
30747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
30847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
30947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    char buffer[kMaxAddressLength];
31047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    memcpy(buffer, start, len);
31147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    buffer[len] = 0;
31247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
31347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    char * colon = ::strchr(buffer, ':');
31447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (!colon) {
31547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      LOG(LS_WARNING) << "Proxy address without port [" << buffer << "]";
31647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      continue;
31747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
31847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
31947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    *colon = 0;
32047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    char * endptr;
32147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    port = static_cast<uint16>(strtol(colon + 1, &endptr, 0));
32247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (*endptr != 0) {
32347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      LOG(LS_WARNING) << "Proxy address with invalid port [" << buffer << "]";
32447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      continue;
32547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
32647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
32747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (char * equals = ::strchr(buffer, '=')) {
32847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      *equals = 0;
32947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      host = equals + 1;
33047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (_stricmp(buffer, "socks") == 0) {
33147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        ptype = PROXY_SOCKS5;
33247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      } else if (_stricmp(buffer, "https") == 0) {
33347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        ptype = PROXY_HTTPS;
33447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      } else {
33547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        LOG(LS_WARNING) << "Proxy address with unknown protocol ["
33647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                        << buffer << "]";
33747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        ptype = PROXY_UNKNOWN;
33847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
33947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    } else {
34047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      host = buffer;
34147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ptype = PROXY_UNKNOWN;
34247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
34347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
34447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (Better(ptype, proxy->type)) {
34547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      proxy->type = ptype;
34647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      proxy->address.SetIP(host);
34747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      proxy->address.SetPort(port);
34847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
34947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
35047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
35147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return proxy->type != PROXY_NONE;
35247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
35347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
35447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgUserAgent GetAgent(const char* agent) {
35547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (agent) {
35647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    std::string agent_str(agent);
35747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (agent_str.find(kFirefoxPattern) != std::string::npos) {
35847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return UA_FIREFOX;
35947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    } else if (agent_str.find(kInternetExplorerPattern) != std::string::npos) {
36047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return UA_INTERNETEXPLORER;
36147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    } else if (agent_str.empty()) {
36247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return UA_UNKNOWN;
36347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
36447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
36547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return UA_OTHER;
36647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
36747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
36847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool EndsWith(const std::string& a, const std::string& b) {
36947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (b.size() > a.size()) {
37047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
37147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
37247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int result = a.compare(a.size() - b.size(), b.size(), b);
37347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return result == 0;
37447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
37547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
37647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool GetFirefoxProfilePath(Pathname* path) {
37747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN)
37847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  wchar_t w_path[MAX_PATH];
37947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (SHGetFolderPath(0, CSIDL_APPDATA, 0, SHGFP_TYPE_CURRENT, w_path) !=
38047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      S_OK) {
38147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_ERROR) << "SHGetFolderPath failed";
38247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
38347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
38447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  path->SetFolder(ToUtf8(w_path, wcslen(w_path)));
38547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  path->AppendFolder("Mozilla");
38647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  path->AppendFolder("Firefox");
38747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
38847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  FSRef fr;
38947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (0 != FSFindFolder(kUserDomain, kApplicationSupportFolderType,
39047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                        kCreateFolder, &fr)) {
39147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_ERROR) << "FSFindFolder failed";
39247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
39347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
39447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  char buffer[NAME_MAX + 1];
39547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (0 != FSRefMakePath(&fr, reinterpret_cast<uint8*>(buffer),
39647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         ARRAY_SIZE(buffer))) {
39747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_ERROR) << "FSRefMakePath failed";
39847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
39947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
40047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  path->SetFolder(std::string(buffer));
40147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  path->AppendFolder("Firefox");
40247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#else
40347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  char* user_home = getenv("HOME");
40447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (user_home == NULL) {
40547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
40647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
40747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  path->SetFolder(std::string(user_home));
40847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  path->AppendFolder(".mozilla");
40947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  path->AppendFolder("firefox");
41047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif  // WEBRTC_WIN
41147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
41247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
41347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
41447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool GetDefaultFirefoxProfile(Pathname* profile_path) {
41547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ASSERT(NULL != profile_path);
41647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Pathname path;
41747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!GetFirefoxProfilePath(&path)) {
41847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
41947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
42047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
42147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if USE_FIREFOX_PROFILES_INI
42247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // [Profile0]
42347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Name=default
42447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // IsRelative=1
42547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Path=Profiles/2de53ejb.default
42647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Default=1
42747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
42847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Note: we are looking for the first entry with "Default=1", or the last
42947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // entry in the file
43047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  path.SetFilename("profiles.ini");
43147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<FileStream> fs(Filesystem::OpenFile(path, "r"));
43247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!fs) {
43347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
43447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
43547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Pathname candidate;
43647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool relative = true;
43747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::string line;
43847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  while (fs->ReadLine(&line) == SR_SUCCESS) {
43947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (line.length() == 0) {
44047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      continue;
44147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
44247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (line.at(0) == '[') {
44347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      relative = true;
44447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      candidate.clear();
44547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    } else if (line.find("IsRelative=") == 0 &&
44647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org               line.length() >= 12) {
44747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // TODO: The initial Linux public launch revealed a fairly
44847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // high number of machines where IsRelative= did not have anything after
44947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // it. Perhaps that is legal profiles.ini syntax?
45047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      relative = (line.at(11) != '0');
45147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    } else if (line.find("Path=") == 0 &&
45247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org               line.length() >= 6) {
45347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (relative) {
45447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        candidate = path;
45547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      } else {
45647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        candidate.clear();
45747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
45847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      candidate.AppendFolder(line.substr(5));
45947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    } else if (line.find("Default=") == 0 &&
46047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org               line.length() >= 9) {
46147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if ((line.at(8) != '0') && !candidate.empty()) {
46247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        break;
46347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
46447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
46547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
46647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  fs->Close();
46747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (candidate.empty()) {
46847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
46947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
47047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  profile_path->SetPathname(candidate.pathname());
47147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
47247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#else // !USE_FIREFOX_PROFILES_INI
47347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  path.AppendFolder("Profiles");
47447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DirectoryIterator* it = Filesystem::IterateDirectory();
47547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  it->Iterate(path);
47647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::string extension(".default");
47747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  while (!EndsWith(it->Name(), extension)) {
47847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (!it->Next()) {
47947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      return false;
48047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
48147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
48247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
48347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  profile_path->SetPathname(path);
48447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  profile->AppendFolder("Profiles");
48547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  profile->AppendFolder(it->Name());
48647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  delete it;
48747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
48847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif // !USE_FIREFOX_PROFILES_INI
48947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
49047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
49147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
49247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
49347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool ReadFirefoxPrefs(const Pathname& filename,
49447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                      const char * prefix,
49547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                      StringMap* settings) {
49647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  scoped_ptr<FileStream> fs(Filesystem::OpenFile(filename, "r"));
49747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!fs) {
49847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_ERROR) << "Failed to open file: " << filename.pathname();
49947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
50047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
50147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
50247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::string line;
50347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  while (fs->ReadLine(&line) == SR_SUCCESS) {
50447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    size_t prefix_len = strlen(prefix);
50547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
50647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // Skip blank lines and too long lines.
50747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if ((line.length() == 0) || (line.length() > kMaxLineLength)
50847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        || (line.at(0) == '#') || line.compare(0, 2, "/*") == 0
50947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        || line.compare(0, 2, " *") == 0) {
51047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      continue;
51147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
51247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
51347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    char buffer[kMaxLineLength];
51447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    strcpyn(buffer, sizeof(buffer), line.c_str());
51547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    int nstart = 0, nend = 0, vstart = 0, vend = 0;
51647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    sscanf(buffer, "user_pref(\"%n%*[^\"]%n\", %n%*[^)]%n);",
51747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org           &nstart, &nend, &vstart, &vend);
51847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (vend > 0) {
51947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      char* name = buffer + nstart;
52047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      name[nend - nstart] = 0;
52147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if ((vend - vstart >= 2) && (buffer[vstart] == '"')) {
52247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        vstart += 1;
52347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        vend -= 1;
52447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
52547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      char* value = buffer + vstart;
52647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      value[vend - vstart] = 0;
52747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if ((strncmp(name, prefix, prefix_len) == 0) && *value) {
52847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        settings->Add(name + prefix_len, value);
52947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
53047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    } else {
53147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      LOG_F(LS_WARNING) << "Unparsed pref [" << buffer << "]";
53247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
53347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
53447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  fs->Close();
53547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
53647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
53747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
53847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool GetFirefoxProxySettings(const char* url, ProxyInfo* proxy) {
53947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Url<char> purl(url);
54047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Pathname path;
54147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool success = false;
54247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (GetDefaultFirefoxProfile(&path)) {
54347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    StringMap settings;
54447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    path.SetFilename("prefs.js");
54547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (ReadFirefoxPrefs(path, "network.proxy.", &settings)) {
54647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      success = true;
54747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      proxy->bypass_list =
54847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          settings.Get("no_proxies_on", "localhost, 127.0.0.1");
54947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (settings.Get("type") == "1") {
55047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        // User has manually specified a proxy, try to figure out what
55147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        // type it is.
55247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        if (ProxyListMatch(purl, proxy->bypass_list.c_str(), ',')) {
55347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          // Our url is in the list of url's to bypass proxy.
55447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        } else if (settings.Get("share_proxy_settings") == "true") {
55547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          proxy->type = PROXY_UNKNOWN;
55647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          proxy->address.SetIP(settings.Get("http"));
55747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          proxy->address.SetPort(atoi(settings.Get("http_port").c_str()));
55847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        } else if (settings.IsSet("socks")) {
55947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          proxy->type = PROXY_SOCKS5;
56047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          proxy->address.SetIP(settings.Get("socks"));
56147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          proxy->address.SetPort(atoi(settings.Get("socks_port").c_str()));
56247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        } else if (settings.IsSet("ssl")) {
56347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          proxy->type = PROXY_HTTPS;
56447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          proxy->address.SetIP(settings.Get("ssl"));
56547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          proxy->address.SetPort(atoi(settings.Get("ssl_port").c_str()));
56647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        } else if (settings.IsSet("http")) {
56747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          proxy->type = PROXY_HTTPS;
56847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          proxy->address.SetIP(settings.Get("http"));
56947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          proxy->address.SetPort(atoi(settings.Get("http_port").c_str()));
57047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        }
57147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      } else if (settings.Get("type") == "2") {
57247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        // Browser is configured to get proxy settings from a given url.
57347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        proxy->autoconfig_url = settings.Get("autoconfig_url").c_str();
57447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      } else if (settings.Get("type") == "4") {
57547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        // Browser is configured to auto detect proxy config.
57647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        proxy->autodetect = true;
57747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      } else {
57847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        // No proxy set.
57947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
58047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
58147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
58247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return success;
58347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
58447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
58547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN)  // Windows specific implementation for reading Internet
58647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org              // Explorer proxy settings.
58747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
58847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgvoid LogGetProxyFault() {
58947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LOG_GLEM(LERROR, WINHTTP) << "WinHttpGetProxyForUrl faulted!!";
59047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
59147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
59247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgBOOL MyWinHttpGetProxyForUrl(pfnWinHttpGetProxyForUrl pWHGPFU,
59347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                             HINTERNET hWinHttp, LPCWSTR url,
59447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                             WINHTTP_AUTOPROXY_OPTIONS *options,
59547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                             WINHTTP_PROXY_INFO *info) {
59647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // WinHttpGetProxyForUrl() can call plugins which can crash.
59747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // In the case of McAfee scriptproxy.dll, it does crash in
59847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // older versions. Try to catch crashes here and treat as an
59947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // error.
60047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  BOOL success = FALSE;
60147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
60247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if (_HAS_EXCEPTIONS == 0)
60347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  __try {
60447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    success = pWHGPFU(hWinHttp, url, options, info);
60547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } __except(EXCEPTION_EXECUTE_HANDLER) {
60647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // This is a separate function to avoid
60747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // Visual C++ error 2712 when compiling with C++ EH
60847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LogGetProxyFault();
60947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
61047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#else
61147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  success = pWHGPFU(hWinHttp, url, options, info);
61247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif  // (_HAS_EXCEPTIONS == 0)
61347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
61447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return success;
61547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
61647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
61747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool IsDefaultBrowserFirefox() {
61847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HKEY key;
61947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LONG result = RegOpenKeyEx(HKEY_CLASSES_ROOT, L"http\\shell\\open\\command",
62047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                             0, KEY_READ, &key);
62147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (ERROR_SUCCESS != result)
62247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
62347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
62447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DWORD size, type;
625b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org  bool success = false;
62647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  result = RegQueryValueEx(key, L"", 0, &type, NULL, &size);
627b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org  if (result == ERROR_SUCCESS && type == REG_SZ) {
628b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org    wchar_t* value = new wchar_t[size+1];
62947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    BYTE* buffer = reinterpret_cast<BYTE*>(value);
63047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    result = RegQueryValueEx(key, L"", 0, &type, buffer, &size);
631b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org    if (result == ERROR_SUCCESS) {
632b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org      // Size returned by RegQueryValueEx is in bytes, convert to number of
633b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org      // wchar_t's.
634b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org      size /= sizeof(value[0]);
635b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org      value[size] = L'\0';
636b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org      for (size_t i = 0; i < size; ++i) {
637b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org        value[i] = tolowercase(value[i]);
638b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org      }
639b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org      success = (NULL != strstr(value, L"firefox.exe"));
64047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
641b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org    delete[] value;
64247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
643b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org
644b2e746e82cec7fbcca409efbcf327cc54d81f795henrike@webrtc.org  RegCloseKey(key);
64547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return success;
64647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
64747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
64847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool GetWinHttpProxySettings(const char* url, ProxyInfo* proxy) {
64947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HMODULE winhttp_handle = LoadLibrary(L"winhttp.dll");
65047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (winhttp_handle == NULL) {
65147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_ERROR) << "Failed to load winhttp.dll.";
65247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
65347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
65447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  WINHTTP_CURRENT_USER_IE_PROXY_CONFIG iecfg;
65547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  memset(&iecfg, 0, sizeof(iecfg));
65647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Url<char> purl(url);
65747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  pfnWinHttpGetIEProxyConfig pWHGIEPC =
65847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      reinterpret_cast<pfnWinHttpGetIEProxyConfig>(
65947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          GetProcAddress(winhttp_handle,
66047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         "WinHttpGetIEProxyConfigForCurrentUser"));
66147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool success = false;
66247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (pWHGIEPC && pWHGIEPC(&iecfg)) {
66347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // We were read proxy config successfully.
66447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    success = true;
66547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (iecfg.fAutoDetect) {
66647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      proxy->autodetect = true;
66747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
66847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (iecfg.lpszAutoConfigUrl) {
66947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      proxy->autoconfig_url = ToUtf8(iecfg.lpszAutoConfigUrl);
67047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      GlobalFree(iecfg.lpszAutoConfigUrl);
67147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
67247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (iecfg.lpszProxyBypass) {
67347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      proxy->bypass_list = ToUtf8(iecfg.lpszProxyBypass);
67447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      GlobalFree(iecfg.lpszProxyBypass);
67547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
67647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (iecfg.lpszProxy) {
67747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (!ProxyListMatch(purl, proxy->bypass_list, ';')) {
67847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        ParseProxy(ToUtf8(iecfg.lpszProxy), proxy);
67947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
68047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      GlobalFree(iecfg.lpszProxy);
68147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
68247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
68347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  FreeLibrary(winhttp_handle);
68447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return success;
68547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
68647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
68747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Uses the WinHTTP API to auto detect proxy for the given url. Firefox and IE
68847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// have slightly different option dialogs for proxy settings. In Firefox,
68947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// either a location of a proxy configuration file can be specified or auto
69047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// detection can be selected. In IE theese two options can be independently
69147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// selected. For the case where both options are selected (only IE) we try to
69247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// fetch the config file first, and if that fails we'll perform an auto
69347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// detection.
69447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//
69547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Returns true if we successfully performed an auto detection not depending on
69647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// whether we found a proxy or not. Returns false on error.
69747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool WinHttpAutoDetectProxyForUrl(const char* agent, const char* url,
69847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                  ProxyInfo* proxy) {
69947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Url<char> purl(url);
70047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool success = true;
70147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HMODULE winhttp_handle = LoadLibrary(L"winhttp.dll");
70247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (winhttp_handle == NULL) {
70347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_ERROR) << "Failed to load winhttp.dll.";
70447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return false;
70547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
70647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  pfnWinHttpOpen pWHO =
70747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      reinterpret_cast<pfnWinHttpOpen>(GetProcAddress(winhttp_handle,
70847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                                      "WinHttpOpen"));
70947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  pfnWinHttpCloseHandle pWHCH =
71047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      reinterpret_cast<pfnWinHttpCloseHandle>(
71147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          GetProcAddress(winhttp_handle, "WinHttpCloseHandle"));
71247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  pfnWinHttpGetProxyForUrl pWHGPFU =
71347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      reinterpret_cast<pfnWinHttpGetProxyForUrl>(
71447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          GetProcAddress(winhttp_handle, "WinHttpGetProxyForUrl"));
71547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (pWHO && pWHCH && pWHGPFU) {
71647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (HINTERNET hWinHttp = pWHO(ToUtf16(agent).c_str(),
71747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                  WINHTTP_ACCESS_TYPE_NO_PROXY,
71847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                  WINHTTP_NO_PROXY_NAME,
71947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                  WINHTTP_NO_PROXY_BYPASS,
72047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                  0)) {
72147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      BOOL result = FALSE;
72247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      WINHTTP_PROXY_INFO info;
72347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      memset(&info, 0, sizeof(info));
72447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (proxy->autodetect) {
72547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        // Use DHCP and DNS to try to find any proxy to use.
72647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        WINHTTP_AUTOPROXY_OPTIONS options;
72747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        memset(&options, 0, sizeof(options));
72847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        options.fAutoLogonIfChallenged = TRUE;
72947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
73047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        options.dwFlags |= WINHTTP_AUTOPROXY_AUTO_DETECT;
73147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        options.dwAutoDetectFlags |= WINHTTP_AUTO_DETECT_TYPE_DHCP
73247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
73347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        result = MyWinHttpGetProxyForUrl(
73447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            pWHGPFU, hWinHttp, ToUtf16(url).c_str(), &options, &info);
73547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
73647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (!result && !proxy->autoconfig_url.empty()) {
73747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        // We have the location of a proxy config file. Download it and
73847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        // execute it to find proxy settings for our url.
73947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        WINHTTP_AUTOPROXY_OPTIONS options;
74047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        memset(&options, 0, sizeof(options));
74147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        memset(&info, 0, sizeof(info));
74247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        options.fAutoLogonIfChallenged = TRUE;
74347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
74447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        std::wstring autoconfig_url16((ToUtf16)(proxy->autoconfig_url));
74547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        options.dwFlags |= WINHTTP_AUTOPROXY_CONFIG_URL;
74647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        options.lpszAutoConfigUrl = autoconfig_url16.c_str();
74747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
74847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        result = MyWinHttpGetProxyForUrl(
74947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            pWHGPFU, hWinHttp, ToUtf16(url).c_str(), &options, &info);
75047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
75147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (result) {
75247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        // Either the given auto config url was valid or auto
75347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        // detection found a proxy on this network.
75447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        if (info.lpszProxy) {
75547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          // TODO: Does this bypass list differ from the list
75647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          // retreived from GetWinHttpProxySettings earlier?
75747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          if (info.lpszProxyBypass) {
75847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            proxy->bypass_list = ToUtf8(info.lpszProxyBypass);
75947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            GlobalFree(info.lpszProxyBypass);
76047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          } else {
76147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            proxy->bypass_list.clear();
76247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          }
76347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          if (!ProxyListMatch(purl, proxy->bypass_list, ';')) {
76447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            // Found proxy for this URL. If parsing the address turns
76547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            // out ok then we are successful.
76647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            success = ParseProxy(ToUtf8(info.lpszProxy), proxy);
76747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          }
76847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          GlobalFree(info.lpszProxy);
76947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        }
77047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      } else {
77147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        // We could not find any proxy for this url.
77247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        LOG(LS_INFO) << "No proxy detected for " << url;
77347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
77447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      pWHCH(hWinHttp);
77547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
77647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else {
77747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_ERROR) << "Failed loading WinHTTP functions.";
77847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    success = false;
77947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
78047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  FreeLibrary(winhttp_handle);
78147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return success;
78247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
78347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
78447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if 0  // Below functions currently not used.
78547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
78647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool GetJsProxySettings(const char* url, ProxyInfo* proxy) {
78747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Url<char> purl(url);
78847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool success = false;
78947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
79047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (HMODULE hModJS = LoadLibrary(_T("jsproxy.dll"))) {
79147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    pfnInternetGetProxyInfo pIGPI =
79247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        reinterpret_cast<pfnInternetGetProxyInfo>(
79347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            GetProcAddress(hModJS, "InternetGetProxyInfo"));
79447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (pIGPI) {
79547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      char proxy[256], host[256];
79647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      memset(proxy, 0, sizeof(proxy));
79747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      char * ptr = proxy;
79847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      DWORD proxylen = sizeof(proxy);
79947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      std::string surl = Utf8String(url);
80047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      DWORD hostlen = _snprintf(host, sizeof(host), "http%s://%S",
80147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                purl.secure() ? "s" : "", purl.server());
80247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (pIGPI(surl.data(), surl.size(), host, hostlen, &ptr, &proxylen)) {
80347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        LOG(INFO) << "Proxy: " << proxy;
80447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      } else {
80547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        LOG_GLE(INFO) << "InternetGetProxyInfo";
80647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
80747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
80847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    FreeLibrary(hModJS);
80947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
81047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return success;
81147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
81247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
81347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool GetWmProxySettings(const char* url, ProxyInfo* proxy) {
81447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Url<char> purl(url);
81547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool success = false;
81647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
81747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  INSNetSourceCreator * nsc = 0;
81847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  HRESULT hr = CoCreateInstance(CLSID_ClientNetManager, 0, CLSCTX_ALL,
81947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                IID_INSNetSourceCreator, (LPVOID *) &nsc);
82047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (SUCCEEDED(hr)) {
82147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (SUCCEEDED(hr = nsc->Initialize())) {
82247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      VARIANT dispatch;
82347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      VariantInit(&dispatch);
82447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (SUCCEEDED(hr = nsc->GetNetSourceAdminInterface(L"http", &dispatch))) {
82547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        IWMSInternalAdminNetSource * ians = 0;
82647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        if (SUCCEEDED(hr = dispatch.pdispVal->QueryInterface(
82747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                IID_IWMSInternalAdminNetSource, (LPVOID *) &ians))) {
82847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          _bstr_t host(purl.server());
82947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          BSTR proxy = 0;
83047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          BOOL bProxyEnabled = FALSE;
83147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          DWORD port, context = 0;
83247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          if (SUCCEEDED(hr = ians->FindProxyForURL(
83347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                  L"http", host, &bProxyEnabled, &proxy, &port, &context))) {
83447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            success = true;
83547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            if (bProxyEnabled) {
83647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org              _bstr_t sproxy = proxy;
83747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org              proxy->ptype = PT_HTTPS;
83847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org              proxy->host = sproxy;
83947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org              proxy->port = port;
84047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            }
84147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          }
84247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          SysFreeString(proxy);
84347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          if (FAILED(hr = ians->ShutdownProxyContext(context))) {
84447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            LOG(LS_INFO) << "IWMSInternalAdminNetSource::ShutdownProxyContext"
84547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                         << "failed: " << hr;
84647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          }
84747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          ians->Release();
84847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        }
84947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
85047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      VariantClear(&dispatch);
85147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (FAILED(hr = nsc->Shutdown())) {
85247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        LOG(LS_INFO) << "INSNetSourceCreator::Shutdown failed: " << hr;
85347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
85447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
85547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    nsc->Release();
85647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
85747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return success;
85847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
85947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
86047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool GetIePerConnectionProxySettings(const char* url, ProxyInfo* proxy) {
86147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Url<char> purl(url);
86247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool success = false;
86347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
86447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  INTERNET_PER_CONN_OPTION_LIST list;
86547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  INTERNET_PER_CONN_OPTION options[3];
86647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  memset(&list, 0, sizeof(list));
86747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  memset(&options, 0, sizeof(options));
86847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
86947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  list.dwSize = sizeof(list);
87047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  list.dwOptionCount = 3;
87147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  list.pOptions = options;
87247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  options[0].dwOption = INTERNET_PER_CONN_FLAGS;
87347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  options[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
87447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  options[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS;
87547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DWORD dwSize = sizeof(list);
87647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
87747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!InternetQueryOption(0, INTERNET_OPTION_PER_CONNECTION_OPTION, &list,
87847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                           &dwSize)) {
87947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_INFO) << "InternetQueryOption failed: " << GetLastError();
88047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else if ((options[0].Value.dwValue & PROXY_TYPE_PROXY) != 0) {
88147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    success = true;
88247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (!ProxyListMatch(purl, nonnull(options[2].Value.pszValue), _T(';'))) {
88347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ParseProxy(nonnull(options[1].Value.pszValue), proxy);
88447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
88547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else if ((options[0].Value.dwValue & PROXY_TYPE_DIRECT) != 0) {
88647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    success = true;
88747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else {
88847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_INFO) << "unknown internet access type: "
88947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                 << options[0].Value.dwValue;
89047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
89147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (options[1].Value.pszValue) {
89247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    GlobalFree(options[1].Value.pszValue);
89347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
89447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (options[2].Value.pszValue) {
89547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    GlobalFree(options[2].Value.pszValue);
89647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
89747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return success;
89847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
89947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
90047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif  // 0
90147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
90247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Uses the InternetQueryOption function to retrieve proxy settings
90347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// from the registry. This will only give us the 'static' settings,
90447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// ie, not any information about auto config etc.
90547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool GetIeLanProxySettings(const char* url, ProxyInfo* proxy) {
90647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Url<char> purl(url);
90747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool success = false;
90847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
90947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  wchar_t buffer[1024];
91047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  memset(buffer, 0, sizeof(buffer));
91147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  INTERNET_PROXY_INFO * info = reinterpret_cast<INTERNET_PROXY_INFO *>(buffer);
91247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DWORD dwSize = sizeof(buffer);
91347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
91447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!InternetQueryOption(0, INTERNET_OPTION_PROXY, info, &dwSize)) {
91547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_INFO) << "InternetQueryOption failed: " << GetLastError();
91647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else if (info->dwAccessType == INTERNET_OPEN_TYPE_DIRECT) {
91747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    success = true;
91847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else if (info->dwAccessType == INTERNET_OPEN_TYPE_PROXY) {
91947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    success = true;
92047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (!ProxyListMatch(purl, nonnull(reinterpret_cast<const char*>(
92147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            info->lpszProxyBypass)), ' ')) {
92247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      ParseProxy(nonnull(reinterpret_cast<const char*>(info->lpszProxy)),
92347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                 proxy);
92447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
92547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else {
92647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_INFO) << "unknown internet access type: " << info->dwAccessType;
92747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
92847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return success;
92947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
93047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
93147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool GetIeProxySettings(const char* agent, const char* url, ProxyInfo* proxy) {
93247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool success = GetWinHttpProxySettings(url, proxy);
93347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!success) {
93447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // TODO: Should always call this if no proxy were detected by
93547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // GetWinHttpProxySettings?
93647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // WinHttp failed. Try using the InternetOptionQuery method instead.
93747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    return GetIeLanProxySettings(url, proxy);
93847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
93947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return true;
94047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
94147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
94247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif  // WEBRTC_WIN
94347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
94447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)  // WEBRTC_MAC && !defined(WEBRTC_IOS) specific implementation for reading system wide
94547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            // proxy settings.
94647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
94747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool p_getProxyInfoForTypeFromDictWithKeys(ProxyInfo* proxy,
94847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                           ProxyType type,
94947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                           const CFDictionaryRef proxyDict,
95047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                           const CFStringRef enabledKey,
95147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                           const CFStringRef hostKey,
95247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                           const CFStringRef portKey) {
95347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // whether or not we set up the proxy info.
95447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool result = false;
95547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
95647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // we use this as a scratch variable for determining if operations
95747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // succeeded.
95847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool converted = false;
95947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
96047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // the data we need to construct the SocketAddress for the proxy.
96147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::string hostname;
96247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  int port;
96347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
96447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if ((proxyDict != NULL) &&
96547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      (CFGetTypeID(proxyDict) == CFDictionaryGetTypeID())) {
96647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // CoreFoundation stuff that we'll have to get from
96747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // the dictionaries and interpret or convert into more usable formats.
96847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    CFNumberRef enabledCFNum;
96947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    CFNumberRef portCFNum;
97047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    CFStringRef hostCFStr;
97147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
97247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    enabledCFNum = (CFNumberRef)CFDictionaryGetValue(proxyDict, enabledKey);
97347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
97447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (p_isCFNumberTrue(enabledCFNum)) {
97547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // let's see if we can get the address and port.
97647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      hostCFStr = (CFStringRef)CFDictionaryGetValue(proxyDict, hostKey);
97747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      converted = p_convertHostCFStringRefToCPPString(hostCFStr, hostname);
97847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (converted) {
97947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        portCFNum = (CFNumberRef)CFDictionaryGetValue(proxyDict, portKey);
98047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        converted = p_convertCFNumberToInt(portCFNum, &port);
98147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        if (converted) {
98247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          // we have something enabled, with a hostname and a port.
98347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          // That's sufficient to set up the proxy info.
98447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          proxy->type = type;
98547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          proxy->address.SetIP(hostname);
98647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          proxy->address.SetPort(port);
98747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          result = true;
98847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        }
98947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
99047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
99147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
99247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
99347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return result;
99447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
99547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
99647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Looks for proxy information in the given dictionary,
99747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// return true if it found sufficient information to define one,
99847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// false otherwise.  This is guaranteed to not change the values in proxy
99947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// unless a full-fledged proxy description was discovered in the dictionary.
100047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// However, at the present time this does not support username or password.
100147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Checks first for a SOCKS proxy, then for HTTPS, then HTTP.
100247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool GetMacProxySettingsFromDictionary(ProxyInfo* proxy,
100347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                       const CFDictionaryRef proxyDict) {
100447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // the function result.
100547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool gotProxy = false;
100647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
100747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
100847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // first we see if there's a SOCKS proxy in place.
100947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  gotProxy = p_getProxyInfoForTypeFromDictWithKeys(proxy,
101047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                                   PROXY_SOCKS5,
101147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                                   proxyDict,
101247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                                   kSCPropNetProxiesSOCKSEnable,
101347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                                   kSCPropNetProxiesSOCKSProxy,
101447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                                   kSCPropNetProxiesSOCKSPort);
101547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
101647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (!gotProxy) {
101747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // okay, no SOCKS proxy, let's look for https.
101847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    gotProxy = p_getProxyInfoForTypeFromDictWithKeys(proxy,
101947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                               PROXY_HTTPS,
102047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                               proxyDict,
102147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                               kSCPropNetProxiesHTTPSEnable,
102247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                               kSCPropNetProxiesHTTPSProxy,
102347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                               kSCPropNetProxiesHTTPSPort);
102447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (!gotProxy) {
102547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // Finally, try HTTP proxy. Note that flute doesn't
102647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // differentiate between HTTPS and HTTP, hence we are using the
102747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // same flute type here, ie. PROXY_HTTPS.
102847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      gotProxy = p_getProxyInfoForTypeFromDictWithKeys(
102947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          proxy, PROXY_HTTPS, proxyDict, kSCPropNetProxiesHTTPEnable,
103047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          kSCPropNetProxiesHTTPProxy, kSCPropNetProxiesHTTPPort);
103147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
103247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
103347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return gotProxy;
103447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
103547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
103647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// TODO(hughv) Update keychain functions. They work on 10.8, but are depricated.
103747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
103847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool p_putPasswordInProxyInfo(ProxyInfo* proxy) {
103947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool result = true;  // by default we assume we're good.
104047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // for all we know there isn't any password.  We'll set to false
104147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // if we find a problem.
104247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
104347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Ask the keychain for an internet password search for the given protocol.
104447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  OSStatus oss = 0;
104547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SecKeychainAttributeList attrList;
104647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  attrList.count = 3;
104747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SecKeychainAttribute attributes[3];
104847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  attrList.attr = attributes;
104947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
105047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  attributes[0].tag = kSecProtocolItemAttr;
105147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  attributes[0].length = sizeof(SecProtocolType);
105247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  SecProtocolType protocol;
105347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  switch (proxy->type) {
105447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    case PROXY_HTTPS :
105547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      protocol = kSecProtocolTypeHTTPS;
105647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      break;
105747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    case PROXY_SOCKS5 :
105847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      protocol = kSecProtocolTypeSOCKS;
105947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      break;
106047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    default :
106147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      LOG(LS_ERROR) << "asked for proxy password for unknown proxy type.";
106247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      result = false;
106347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      break;
106447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
106547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  attributes[0].data = &protocol;
106647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
106747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  UInt32 port = proxy->address.port();
106847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  attributes[1].tag = kSecPortItemAttr;
106947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  attributes[1].length = sizeof(UInt32);
107047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  attributes[1].data = &port;
107147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
107247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::string ip = proxy->address.ipaddr().ToString();
107347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  attributes[2].tag = kSecServerItemAttr;
107447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  attributes[2].length = ip.length();
107547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  attributes[2].data = const_cast<char*>(ip.c_str());
107647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
107747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (result) {
107847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_INFO) << "trying to get proxy username/password";
107947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    SecKeychainSearchRef sref;
108047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    oss = SecKeychainSearchCreateFromAttributes(NULL,
108147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                                kSecInternetPasswordItemClass,
108247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                                &attrList, &sref);
108347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (0 == oss) {
108447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      LOG(LS_INFO) << "SecKeychainSearchCreateFromAttributes was good";
108547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // Get the first item, if there is one.
108647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      SecKeychainItemRef iref;
108747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      oss = SecKeychainSearchCopyNext(sref, &iref);
108847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (0 == oss) {
108947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        LOG(LS_INFO) << "...looks like we have the username/password data";
109047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        // If there is, get the username and the password.
109147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
109247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        SecKeychainAttributeInfo attribsToGet;
109347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        attribsToGet.count = 1;
109447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        UInt32 tag = kSecAccountItemAttr;
109547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        UInt32 format = CSSM_DB_ATTRIBUTE_FORMAT_STRING;
109647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        void *data;
109747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        UInt32 length;
109847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        SecKeychainAttributeList *localList;
109947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
110047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        attribsToGet.tag = &tag;
110147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        attribsToGet.format = &format;
110247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        OSStatus copyres = SecKeychainItemCopyAttributesAndData(iref,
110347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                                                &attribsToGet,
110447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                                                NULL,
110547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                                                &localList,
110647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                                                &length,
110747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                                                &data);
110847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        if (0 == copyres) {
110947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          LOG(LS_INFO) << "...and we can pull it out.";
111047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          // now, we know from experimentation (sadly not from docs)
111147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          // that the username is in the local attribute list,
111247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          // and the password in the data,
111347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          // both without null termination but with info on their length.
111447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          // grab the password from the data.
111547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          std::string password;
111647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          password.append(static_cast<const char*>(data), length);
111747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
111847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          // make the password into a CryptString
111947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          // huh, at the time of writing, you can't.
112047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          // so we'll skip that for now and come back to it later.
112147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
112247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          // now put the username in the proxy.
112347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          if (1 <= localList->attr->length) {
112447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            proxy->username.append(
112547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                static_cast<const char*>(localList->attr->data),
112647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                localList->attr->length);
112747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            LOG(LS_INFO) << "username is " << proxy->username;
112847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          } else {
112947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            LOG(LS_ERROR) << "got keychain entry with no username";
113047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org            result = false;
113147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          }
113247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        } else {
113347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          LOG(LS_ERROR) << "couldn't copy info from keychain.";
113447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org          result = false;
113547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        }
113647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        SecKeychainItemFreeAttributesAndData(localList, data);
113747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      } else if (errSecItemNotFound == oss) {
113847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        LOG(LS_INFO) << "...username/password info not found";
113947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      } else {
114047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        // oooh, neither 0 nor itemNotFound.
114147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        LOG(LS_ERROR) << "Couldn't get keychain information, error code" << oss;
114247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        result = false;
114347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
114447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    } else if (errSecItemNotFound == oss) {  // noop
114547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    } else {
114647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // oooh, neither 0 nor itemNotFound.
114747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      LOG(LS_ERROR) << "Couldn't get keychain information, error code" << oss;
114847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      result = false;
114947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
115047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
115147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
115247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return result;
115347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
115447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
115547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool GetMacProxySettings(ProxyInfo* proxy) {
115647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // based on the Apple Technical Q&A QA1234
115747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // http://developer.apple.com/qa/qa2001/qa1234.html
115847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  CFDictionaryRef proxyDict = SCDynamicStoreCopyProxies(NULL);
115947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool result = false;
116047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
116147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (proxyDict != NULL) {
116247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // sending it off to another function makes it easier to unit test
116347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // since we can make our own dictionary to hand to that function.
116447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    result = GetMacProxySettingsFromDictionary(proxy, proxyDict);
116547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
116647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (result) {
116747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      result = p_putPasswordInProxyInfo(proxy);
116847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
116947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
117047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // We created the dictionary with something that had the
117147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // word 'copy' in it, so we have to release it, according
117247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // to the Carbon memory management standards.
117347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    CFRelease(proxyDict);
117447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  } else {
117547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    LOG(LS_ERROR) << "SCDynamicStoreCopyProxies failed";
117647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
117747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
117847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return result;
117947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
118047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif  // WEBRTC_MAC && !defined(WEBRTC_IOS)
118147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
118247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool AutoDetectProxySettings(const char* agent, const char* url,
118347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                             ProxyInfo* proxy) {
118447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN)
118547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return WinHttpAutoDetectProxyForUrl(agent, url, proxy);
118647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#else
118747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  LOG(LS_WARNING) << "Proxy auto-detection not implemented for this platform";
118847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return false;
118947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif
119047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
119147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
119247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool GetSystemDefaultProxySettings(const char* agent, const char* url,
119347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                   ProxyInfo* proxy) {
119447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN)
119547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return GetIeProxySettings(agent, url, proxy);
119647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
119747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return GetMacProxySettings(proxy);
119847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#else
119947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // TODO: Get System settings if browser is not firefox.
120047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return GetFirefoxProxySettings(url, proxy);
120147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif
120247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
120347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
120447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgbool GetProxySettingsForUrl(const char* agent, const char* url,
120547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                            ProxyInfo* proxy, bool long_operation) {
120647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  UserAgent a = GetAgent(agent);
120747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool result;
120847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  switch (a) {
120947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    case UA_FIREFOX: {
121047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      result = GetFirefoxProxySettings(url, proxy);
121147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      break;
121247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
121347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#if defined(WEBRTC_WIN)
121447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    case UA_INTERNETEXPLORER:
121547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      result = GetIeProxySettings(agent, url, proxy);
121647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      break;
121747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    case UA_UNKNOWN:
121847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // Agent not defined, check default browser.
121947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      if (IsDefaultBrowserFirefox()) {
122047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        result = GetFirefoxProxySettings(url, proxy);
122147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      } else {
122247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org        result = GetIeProxySettings(agent, url, proxy);
122347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      }
122447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      break;
122547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif  // WEBRTC_WIN
122647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    default:
122747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      result = GetSystemDefaultProxySettings(agent, url, proxy);
122847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      break;
122947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
123047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
123147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // TODO: Consider using the 'long_operation' parameter to
123247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // decide whether to do the auto detection.
123347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  if (result && (proxy->autodetect ||
123447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                 !proxy->autoconfig_url.empty())) {
123547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    // Use WinHTTP to auto detect proxy for us.
123647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    result = AutoDetectProxySettings(agent, url, proxy);
123747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    if (!result) {
123847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // Either auto detection is not supported or we simply didn't
123947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      // find any proxy, reset type.
124047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      proxy->type = rtc::PROXY_NONE;
124147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    }
124247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
124347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  return result;
124447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}
124547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
124647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}  // namespace rtc
1247