/*
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/base/proxydetect.h"

#if defined(WEBRTC_WIN)
#include "webrtc/base/win32.h"
#include <shlobj.h>
#endif  // WEBRTC_WIN

#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
#include <SystemConfiguration/SystemConfiguration.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CoreServices/CoreServices.h>
#include <Security/Security.h>
#include "macconversion.h"
#endif

#ifdef WEBRTC_IOS
#include <CFNetwork/CFNetwork.h>
#include "macconversion.h"
#endif

#include <map>
#include <memory>

#include "webrtc/base/arraysize.h"
#include "webrtc/base/fileutils.h"
#include "webrtc/base/httpcommon.h"
#include "webrtc/base/httpcommon-inl.h"
#include "webrtc/base/pathutils.h"
#include "webrtc/base/stringutils.h"

#if defined(WEBRTC_WIN)
#define _TRY_WINHTTP 1
#define _TRY_JSPROXY 0
#define _TRY_WM_FINDPROXY 0
#define _TRY_IE_LAN_SETTINGS 1
#endif  // WEBRTC_WIN

// For all platforms try Firefox.
#define _TRY_FIREFOX 1

// Use profiles.ini to find the correct profile for this user.
// If not set, we'll just look for the default one.
#define USE_FIREFOX_PROFILES_INI 1

static const size_t kMaxLineLength = 1024;
static const char kFirefoxPattern[] = "Firefox";
static const char kInternetExplorerPattern[] = "MSIE";

struct StringMap {
 public:
  void Add(const char * name, const char * value) { map_[name] = value; }
  const std::string& Get(const char * name, const char * def = "") const {
    std::map<std::string, std::string>::const_iterator it =
        map_.find(name);
    if (it != map_.end())
      return it->second;
    def_ = def;
    return def_;
  }
  bool IsSet(const char * name) const {
    return (map_.find(name) != map_.end());
  }
 private:
  std::map<std::string, std::string> map_;
  mutable std::string def_;
};

enum UserAgent {
  UA_FIREFOX,
  UA_INTERNETEXPLORER,
  UA_OTHER,
  UA_UNKNOWN
};

#if _TRY_WINHTTP
//#include <winhttp.h>
// Note: From winhttp.h

const char WINHTTP[] = "winhttp";

typedef LPVOID HINTERNET;

typedef struct {
  DWORD  dwAccessType;      // see WINHTTP_ACCESS_* types below
  LPWSTR lpszProxy;         // proxy server list
  LPWSTR lpszProxyBypass;   // proxy bypass list
} WINHTTP_PROXY_INFO, * LPWINHTTP_PROXY_INFO;

typedef struct {
  DWORD   dwFlags;
  DWORD   dwAutoDetectFlags;
  LPCWSTR lpszAutoConfigUrl;
  LPVOID  lpvReserved;
  DWORD   dwReserved;
  BOOL    fAutoLogonIfChallenged;
} WINHTTP_AUTOPROXY_OPTIONS;

typedef struct {
  BOOL    fAutoDetect;
  LPWSTR  lpszAutoConfigUrl;
  LPWSTR  lpszProxy;
  LPWSTR  lpszProxyBypass;
} WINHTTP_CURRENT_USER_IE_PROXY_CONFIG;

extern "C" {
  typedef HINTERNET (WINAPI * pfnWinHttpOpen)
      (
          IN LPCWSTR pwszUserAgent,
          IN DWORD   dwAccessType,
          IN LPCWSTR pwszProxyName   OPTIONAL,
          IN LPCWSTR pwszProxyBypass OPTIONAL,
          IN DWORD   dwFlags
          );
  typedef BOOL (STDAPICALLTYPE * pfnWinHttpCloseHandle)
      (
          IN HINTERNET hInternet
          );
  typedef BOOL (STDAPICALLTYPE * pfnWinHttpGetProxyForUrl)
      (
          IN  HINTERNET                   hSession,
          IN  LPCWSTR                     lpcwszUrl,
          IN  WINHTTP_AUTOPROXY_OPTIONS * pAutoProxyOptions,
          OUT WINHTTP_PROXY_INFO *        pProxyInfo
          );
  typedef BOOL (STDAPICALLTYPE * pfnWinHttpGetIEProxyConfig)
      (
          IN OUT WINHTTP_CURRENT_USER_IE_PROXY_CONFIG * pProxyConfig
          );

} // extern "C"

#define WINHTTP_AUTOPROXY_AUTO_DETECT           0x00000001
#define WINHTTP_AUTOPROXY_CONFIG_URL            0x00000002
#define WINHTTP_AUTOPROXY_RUN_INPROCESS         0x00010000
#define WINHTTP_AUTOPROXY_RUN_OUTPROCESS_ONLY   0x00020000
#define WINHTTP_AUTO_DETECT_TYPE_DHCP           0x00000001
#define WINHTTP_AUTO_DETECT_TYPE_DNS_A          0x00000002
#define WINHTTP_ACCESS_TYPE_DEFAULT_PROXY               0
#define WINHTTP_ACCESS_TYPE_NO_PROXY                    1
#define WINHTTP_ACCESS_TYPE_NAMED_PROXY                 3
#define WINHTTP_NO_PROXY_NAME     NULL
#define WINHTTP_NO_PROXY_BYPASS   NULL

#endif // _TRY_WINHTTP

#if _TRY_JSPROXY
extern "C" {
  typedef BOOL (STDAPICALLTYPE * pfnInternetGetProxyInfo)
      (
          LPCSTR lpszUrl,
          DWORD dwUrlLength,
          LPSTR lpszUrlHostName,
          DWORD dwUrlHostNameLength,
          LPSTR * lplpszProxyHostName,
          LPDWORD lpdwProxyHostNameLength
          );
} // extern "C"
#endif // _TRY_JSPROXY

#if _TRY_WM_FINDPROXY
#include <comutil.h>
#include <wmnetsourcecreator.h>
#include <wmsinternaladminnetsource.h>
#endif // _TRY_WM_FINDPROXY

#if _TRY_IE_LAN_SETTINGS
#include <wininet.h>
#include <string>
#endif // _TRY_IE_LAN_SETTINGS

namespace rtc {

//////////////////////////////////////////////////////////////////////
// Utility Functions
//////////////////////////////////////////////////////////////////////

#if defined(WEBRTC_WIN)
#ifdef _UNICODE

typedef std::wstring tstring;
std::string Utf8String(const tstring& str) { return ToUtf8(str); }

#else  // !_UNICODE

typedef std::string tstring;
std::string Utf8String(const tstring& str) { return str; }

#endif  // !_UNICODE
#endif  // WEBRTC_WIN

bool ProxyItemMatch(const Url<char>& url, char * item, size_t len) {
  // hostname:443
  if (char * port = ::strchr(item, ':')) {
    *port++ = '\0';
    if (url.port() != atol(port)) {
      return false;
    }
  }

  // A.B.C.D or A.B.C.D/24
  int a, b, c, d, m;
  int match = sscanf(item, "%d.%d.%d.%d/%d", &a, &b, &c, &d, &m);
  if (match >= 4) {
    uint32_t ip = ((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) |
                  (d & 0xFF);
    if ((match < 5) || (m > 32))
      m = 32;
    else if (m < 0)
      m = 0;
    uint32_t mask = (m == 0) ? 0 : (~0UL) << (32 - m);
    SocketAddress addr(url.host(), 0);
    // TODO: Support IPv6 proxyitems. This code block is IPv4 only anyway.
    return !addr.IsUnresolvedIP() &&
        ((addr.ipaddr().v4AddressAsHostOrderInteger() & mask) == (ip & mask));
  }

  // .foo.com
  if (*item == '.') {
    size_t hostlen = url.host().length();
    return (hostlen > len)
        && (stricmp(url.host().c_str() + (hostlen - len), item) == 0);
  }

  // localhost or www.*.com
  if (!string_match(url.host().c_str(), item))
    return false;

  return true;
}

bool ProxyListMatch(const Url<char>& url, const std::string& proxy_list,
                    char sep) {
  const size_t BUFSIZE = 256;
  char buffer[BUFSIZE];
  const char* list = proxy_list.c_str();
  while (*list) {
    // Remove leading space
    if (isspace(*list)) {
      ++list;
      continue;
    }
    // Break on separator
    size_t len;
    const char * start = list;
    if (const char * end = ::strchr(list, sep)) {
      len = (end - list);
      list += len + 1;
    } else {
      len = strlen(list);
      list += len;
    }
    // Remove trailing space
    while ((len > 0) && isspace(start[len-1]))
      --len;
    // Check for oversized entry
    if (len >= BUFSIZE)
      continue;
    memcpy(buffer, start, len);
    buffer[len] = 0;
    if (!ProxyItemMatch(url, buffer, len))
      continue;
    return true;
  }
  return false;
}

bool Better(ProxyType lhs, const ProxyType rhs) {
  // PROXY_NONE, PROXY_HTTPS, PROXY_SOCKS5, PROXY_UNKNOWN
  const int PROXY_VALUE[5] = { 0, 2, 3, 1 };
  return (PROXY_VALUE[lhs] > PROXY_VALUE[rhs]);
}

bool ParseProxy(const std::string& saddress, ProxyInfo* proxy) {
  const size_t kMaxAddressLength = 1024;
  // Allow semicolon, space, or tab as an address separator
  const char* const kAddressSeparator = " ;\t";

  ProxyType ptype;
  std::string host;
  uint16_t port;

  const char* address = saddress.c_str();
  while (*address) {
    size_t len;
    const char * start = address;
    if (const char * sep = strchr(address, kAddressSeparator)) {
      len = (sep - address);
      address += len + 1;
      while (*address != '\0' && ::strchr(kAddressSeparator, *address)) {
        address += 1;
      }
    } else {
      len = strlen(address);
      address += len;
    }

    if (len > kMaxAddressLength - 1) {
      LOG(LS_WARNING) << "Proxy address too long [" << start << "]";
      continue;
    }

    char buffer[kMaxAddressLength];
    memcpy(buffer, start, len);
    buffer[len] = 0;

    char * colon = ::strchr(buffer, ':');
    if (!colon) {
      LOG(LS_WARNING) << "Proxy address without port [" << buffer << "]";
      continue;
    }

    *colon = 0;
    char * endptr;
    port = static_cast<uint16_t>(strtol(colon + 1, &endptr, 0));
    if (*endptr != 0) {
      LOG(LS_WARNING) << "Proxy address with invalid port [" << buffer << "]";
      continue;
    }

    if (char * equals = ::strchr(buffer, '=')) {
      *equals = 0;
      host = equals + 1;
      if (_stricmp(buffer, "socks") == 0) {
        ptype = PROXY_SOCKS5;
      } else if (_stricmp(buffer, "https") == 0) {
        ptype = PROXY_HTTPS;
      } else {
        LOG(LS_WARNING) << "Proxy address with unknown protocol ["
                        << buffer << "]";
        ptype = PROXY_UNKNOWN;
      }
    } else {
      host = buffer;
      ptype = PROXY_UNKNOWN;
    }

    if (Better(ptype, proxy->type)) {
      proxy->type = ptype;
      proxy->address.SetIP(host);
      proxy->address.SetPort(port);
    }
  }

  return proxy->type != PROXY_NONE;
}

UserAgent GetAgent(const char* agent) {
  if (agent) {
    std::string agent_str(agent);
    if (agent_str.find(kFirefoxPattern) != std::string::npos) {
      return UA_FIREFOX;
    } else if (agent_str.find(kInternetExplorerPattern) != std::string::npos) {
      return UA_INTERNETEXPLORER;
    } else if (agent_str.empty()) {
      return UA_UNKNOWN;
    }
  }
  return UA_OTHER;
}

bool EndsWith(const std::string& a, const std::string& b) {
  if (b.size() > a.size()) {
    return false;
  }
  int result = a.compare(a.size() - b.size(), b.size(), b);
  return result == 0;
}

bool GetFirefoxProfilePath(Pathname* path) {
#if defined(WEBRTC_WIN)
  wchar_t w_path[MAX_PATH];
  if (SHGetFolderPath(0, CSIDL_APPDATA, 0, SHGFP_TYPE_CURRENT, w_path) !=
      S_OK) {
    LOG(LS_ERROR) << "SHGetFolderPath failed";
    return false;
  }
  path->SetFolder(ToUtf8(w_path, wcslen(w_path)));
  path->AppendFolder("Mozilla");
  path->AppendFolder("Firefox");
#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
  FSRef fr;
  if (0 != FSFindFolder(kUserDomain, kApplicationSupportFolderType,
                        kCreateFolder, &fr)) {
    LOG(LS_ERROR) << "FSFindFolder failed";
    return false;
  }
  char buffer[NAME_MAX + 1];
  if (0 != FSRefMakePath(&fr, reinterpret_cast<uint8_t*>(buffer),
                         arraysize(buffer))) {
    LOG(LS_ERROR) << "FSRefMakePath failed";
    return false;
  }
  path->SetFolder(std::string(buffer));
  path->AppendFolder("Firefox");
#else
  char* user_home = getenv("HOME");
  if (user_home == NULL) {
    return false;
  }
  path->SetFolder(std::string(user_home));
  path->AppendFolder(".mozilla");
  path->AppendFolder("firefox");
#endif  // WEBRTC_WIN
  return true;
}

bool GetDefaultFirefoxProfile(Pathname* profile_path) {
  ASSERT(NULL != profile_path);
  Pathname path;
  if (!GetFirefoxProfilePath(&path)) {
    return false;
  }

#if USE_FIREFOX_PROFILES_INI
  // [Profile0]
  // Name=default
  // IsRelative=1
  // Path=Profiles/2de53ejb.default
  // Default=1

  // Note: we are looking for the first entry with "Default=1", or the last
  // entry in the file
  path.SetFilename("profiles.ini");
  std::unique_ptr<FileStream> fs(Filesystem::OpenFile(path, "r"));
  if (!fs) {
    return false;
  }
  Pathname candidate;
  bool relative = true;
  std::string line;
  while (fs->ReadLine(&line) == SR_SUCCESS) {
    if (line.length() == 0) {
      continue;
    }
    if (line.at(0) == '[') {
      relative = true;
      candidate.clear();
    } else if (line.find("IsRelative=") == 0 &&
               line.length() >= 12) {
      // TODO: The initial Linux public launch revealed a fairly
      // high number of machines where IsRelative= did not have anything after
      // it. Perhaps that is legal profiles.ini syntax?
      relative = (line.at(11) != '0');
    } else if (line.find("Path=") == 0 &&
               line.length() >= 6) {
      if (relative) {
        candidate = path;
      } else {
        candidate.clear();
      }
      candidate.AppendFolder(line.substr(5));
    } else if (line.find("Default=") == 0 &&
               line.length() >= 9) {
      if ((line.at(8) != '0') && !candidate.empty()) {
        break;
      }
    }
  }
  fs->Close();
  if (candidate.empty()) {
    return false;
  }
  profile_path->SetPathname(candidate.pathname());

#else // !USE_FIREFOX_PROFILES_INI
  path.AppendFolder("Profiles");
  DirectoryIterator* it = Filesystem::IterateDirectory();
  it->Iterate(path);
  std::string extension(".default");
  while (!EndsWith(it->Name(), extension)) {
    if (!it->Next()) {
      return false;
    }
  }

  profile_path->SetPathname(path);
  profile->AppendFolder("Profiles");
  profile->AppendFolder(it->Name());
  delete it;

#endif // !USE_FIREFOX_PROFILES_INI

  return true;
}

bool ReadFirefoxPrefs(const Pathname& filename,
                      const char * prefix,
                      StringMap* settings) {
  std::unique_ptr<FileStream> fs(Filesystem::OpenFile(filename, "r"));
  if (!fs) {
    LOG(LS_ERROR) << "Failed to open file: " << filename.pathname();
    return false;
  }

  std::string line;
  while (fs->ReadLine(&line) == SR_SUCCESS) {
    size_t prefix_len = strlen(prefix);

    // Skip blank lines and too long lines.
    if ((line.length() == 0) || (line.length() > kMaxLineLength)
        || (line.at(0) == '#') || line.compare(0, 2, "/*") == 0
        || line.compare(0, 2, " *") == 0) {
      continue;
    }

    char buffer[kMaxLineLength];
    strcpyn(buffer, sizeof(buffer), line.c_str());
    int nstart = 0, nend = 0, vstart = 0, vend = 0;
    sscanf(buffer, "user_pref(\"%n%*[^\"]%n\", %n%*[^)]%n);",
           &nstart, &nend, &vstart, &vend);
    if (vend > 0) {
      char* name = buffer + nstart;
      name[nend - nstart] = 0;
      if ((vend - vstart >= 2) && (buffer[vstart] == '"')) {
        vstart += 1;
        vend -= 1;
      }
      char* value = buffer + vstart;
      value[vend - vstart] = 0;
      if ((strncmp(name, prefix, prefix_len) == 0) && *value) {
        settings->Add(name + prefix_len, value);
      }
    } else {
      LOG_F(LS_WARNING) << "Unparsed pref [" << buffer << "]";
    }
  }
  fs->Close();
  return true;
}

bool GetFirefoxProxySettings(const char* url, ProxyInfo* proxy) {
  Url<char> purl(url);
  Pathname path;
  bool success = false;
  if (GetDefaultFirefoxProfile(&path)) {
    StringMap settings;
    path.SetFilename("prefs.js");
    if (ReadFirefoxPrefs(path, "network.proxy.", &settings)) {
      success = true;
      proxy->bypass_list =
          settings.Get("no_proxies_on", "localhost, 127.0.0.1");
      if (settings.Get("type") == "1") {
        // User has manually specified a proxy, try to figure out what
        // type it is.
        if (ProxyListMatch(purl, proxy->bypass_list.c_str(), ',')) {
          // Our url is in the list of url's to bypass proxy.
        } else if (settings.Get("share_proxy_settings") == "true") {
          proxy->type = PROXY_UNKNOWN;
          proxy->address.SetIP(settings.Get("http"));
          proxy->address.SetPort(atoi(settings.Get("http_port").c_str()));
        } else if (settings.IsSet("socks")) {
          proxy->type = PROXY_SOCKS5;
          proxy->address.SetIP(settings.Get("socks"));
          proxy->address.SetPort(atoi(settings.Get("socks_port").c_str()));
        } else if (settings.IsSet("ssl")) {
          proxy->type = PROXY_HTTPS;
          proxy->address.SetIP(settings.Get("ssl"));
          proxy->address.SetPort(atoi(settings.Get("ssl_port").c_str()));
        } else if (settings.IsSet("http")) {
          proxy->type = PROXY_HTTPS;
          proxy->address.SetIP(settings.Get("http"));
          proxy->address.SetPort(atoi(settings.Get("http_port").c_str()));
        }
      } else if (settings.Get("type") == "2") {
        // Browser is configured to get proxy settings from a given url.
        proxy->autoconfig_url = settings.Get("autoconfig_url").c_str();
      } else if (settings.Get("type") == "4") {
        // Browser is configured to auto detect proxy config.
        proxy->autodetect = true;
      } else {
        // No proxy set.
      }
    }
  }
  return success;
}

#if defined(WEBRTC_WIN)  // Windows specific implementation for reading Internet
              // Explorer proxy settings.

void LogGetProxyFault() {
  LOG_GLEM(LERROR, WINHTTP) << "WinHttpGetProxyForUrl faulted!!";
}

BOOL MyWinHttpGetProxyForUrl(pfnWinHttpGetProxyForUrl pWHGPFU,
                             HINTERNET hWinHttp, LPCWSTR url,
                             WINHTTP_AUTOPROXY_OPTIONS *options,
                             WINHTTP_PROXY_INFO *info) {
  // WinHttpGetProxyForUrl() can call plugins which can crash.
  // In the case of McAfee scriptproxy.dll, it does crash in
  // older versions. Try to catch crashes here and treat as an
  // error.
  BOOL success = FALSE;

#if (_HAS_EXCEPTIONS == 0)
  __try {
    success = pWHGPFU(hWinHttp, url, options, info);
  } __except(EXCEPTION_EXECUTE_HANDLER) {
    // This is a separate function to avoid
    // Visual C++ error 2712 when compiling with C++ EH
    LogGetProxyFault();
  }
#else
  success = pWHGPFU(hWinHttp, url, options, info);
#endif  // (_HAS_EXCEPTIONS == 0)

  return success;
}

bool IsDefaultBrowserFirefox() {
  HKEY key;
  LONG result = RegOpenKeyEx(HKEY_CLASSES_ROOT, L"http\\shell\\open\\command",
                             0, KEY_READ, &key);
  if (ERROR_SUCCESS != result)
    return false;

  DWORD size, type;
  bool success = false;
  result = RegQueryValueEx(key, L"", 0, &type, NULL, &size);
  if (result == ERROR_SUCCESS && type == REG_SZ) {
    wchar_t* value = new wchar_t[size+1];
    BYTE* buffer = reinterpret_cast<BYTE*>(value);
    result = RegQueryValueEx(key, L"", 0, &type, buffer, &size);
    if (result == ERROR_SUCCESS) {
      // Size returned by RegQueryValueEx is in bytes, convert to number of
      // wchar_t's.
      size /= sizeof(value[0]);
      value[size] = L'\0';
      for (size_t i = 0; i < size; ++i) {
        value[i] = tolowercase(value[i]);
      }
      success = (NULL != strstr(value, L"firefox.exe"));
    }
    delete[] value;
  }

  RegCloseKey(key);
  return success;
}

bool GetWinHttpProxySettings(const char* url, ProxyInfo* proxy) {
  HMODULE winhttp_handle = LoadLibrary(L"winhttp.dll");
  if (winhttp_handle == NULL) {
    LOG(LS_ERROR) << "Failed to load winhttp.dll.";
    return false;
  }
  WINHTTP_CURRENT_USER_IE_PROXY_CONFIG iecfg;
  memset(&iecfg, 0, sizeof(iecfg));
  Url<char> purl(url);
  pfnWinHttpGetIEProxyConfig pWHGIEPC =
      reinterpret_cast<pfnWinHttpGetIEProxyConfig>(
          GetProcAddress(winhttp_handle,
                         "WinHttpGetIEProxyConfigForCurrentUser"));
  bool success = false;
  if (pWHGIEPC && pWHGIEPC(&iecfg)) {
    // We were read proxy config successfully.
    success = true;
    if (iecfg.fAutoDetect) {
      proxy->autodetect = true;
    }
    if (iecfg.lpszAutoConfigUrl) {
      proxy->autoconfig_url = ToUtf8(iecfg.lpszAutoConfigUrl);
      GlobalFree(iecfg.lpszAutoConfigUrl);
    }
    if (iecfg.lpszProxyBypass) {
      proxy->bypass_list = ToUtf8(iecfg.lpszProxyBypass);
      GlobalFree(iecfg.lpszProxyBypass);
    }
    if (iecfg.lpszProxy) {
      if (!ProxyListMatch(purl, proxy->bypass_list, ';')) {
        ParseProxy(ToUtf8(iecfg.lpszProxy), proxy);
      }
      GlobalFree(iecfg.lpszProxy);
    }
  }
  FreeLibrary(winhttp_handle);
  return success;
}

// Uses the WinHTTP API to auto detect proxy for the given url. Firefox and IE
// have slightly different option dialogs for proxy settings. In Firefox,
// either a location of a proxy configuration file can be specified or auto
// detection can be selected. In IE theese two options can be independently
// selected. For the case where both options are selected (only IE) we try to
// fetch the config file first, and if that fails we'll perform an auto
// detection.
//
// Returns true if we successfully performed an auto detection not depending on
// whether we found a proxy or not. Returns false on error.
bool WinHttpAutoDetectProxyForUrl(const char* agent, const char* url,
                                  ProxyInfo* proxy) {
  Url<char> purl(url);
  bool success = true;
  HMODULE winhttp_handle = LoadLibrary(L"winhttp.dll");
  if (winhttp_handle == NULL) {
    LOG(LS_ERROR) << "Failed to load winhttp.dll.";
    return false;
  }
  pfnWinHttpOpen pWHO =
      reinterpret_cast<pfnWinHttpOpen>(GetProcAddress(winhttp_handle,
                                                      "WinHttpOpen"));
  pfnWinHttpCloseHandle pWHCH =
      reinterpret_cast<pfnWinHttpCloseHandle>(
          GetProcAddress(winhttp_handle, "WinHttpCloseHandle"));
  pfnWinHttpGetProxyForUrl pWHGPFU =
      reinterpret_cast<pfnWinHttpGetProxyForUrl>(
          GetProcAddress(winhttp_handle, "WinHttpGetProxyForUrl"));
  if (pWHO && pWHCH && pWHGPFU) {
    if (HINTERNET hWinHttp = pWHO(ToUtf16(agent).c_str(),
                                  WINHTTP_ACCESS_TYPE_NO_PROXY,
                                  WINHTTP_NO_PROXY_NAME,
                                  WINHTTP_NO_PROXY_BYPASS,
                                  0)) {
      BOOL result = FALSE;
      WINHTTP_PROXY_INFO info;
      memset(&info, 0, sizeof(info));
      if (proxy->autodetect) {
        // Use DHCP and DNS to try to find any proxy to use.
        WINHTTP_AUTOPROXY_OPTIONS options;
        memset(&options, 0, sizeof(options));
        options.fAutoLogonIfChallenged = TRUE;

        options.dwFlags |= WINHTTP_AUTOPROXY_AUTO_DETECT;
        options.dwAutoDetectFlags |= WINHTTP_AUTO_DETECT_TYPE_DHCP
            | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
        result = MyWinHttpGetProxyForUrl(
            pWHGPFU, hWinHttp, ToUtf16(url).c_str(), &options, &info);
      }
      if (!result && !proxy->autoconfig_url.empty()) {
        // We have the location of a proxy config file. Download it and
        // execute it to find proxy settings for our url.
        WINHTTP_AUTOPROXY_OPTIONS options;
        memset(&options, 0, sizeof(options));
        memset(&info, 0, sizeof(info));
        options.fAutoLogonIfChallenged = TRUE;

        std::wstring autoconfig_url16((ToUtf16)(proxy->autoconfig_url));
        options.dwFlags |= WINHTTP_AUTOPROXY_CONFIG_URL;
        options.lpszAutoConfigUrl = autoconfig_url16.c_str();

        result = MyWinHttpGetProxyForUrl(
            pWHGPFU, hWinHttp, ToUtf16(url).c_str(), &options, &info);
      }
      if (result) {
        // Either the given auto config url was valid or auto
        // detection found a proxy on this network.
        if (info.lpszProxy) {
          // TODO: Does this bypass list differ from the list
          // retreived from GetWinHttpProxySettings earlier?
          if (info.lpszProxyBypass) {
            proxy->bypass_list = ToUtf8(info.lpszProxyBypass);
            GlobalFree(info.lpszProxyBypass);
          } else {
            proxy->bypass_list.clear();
          }
          if (!ProxyListMatch(purl, proxy->bypass_list, ';')) {
            // Found proxy for this URL. If parsing the address turns
            // out ok then we are successful.
            success = ParseProxy(ToUtf8(info.lpszProxy), proxy);
          }
          GlobalFree(info.lpszProxy);
        }
      } else {
        // We could not find any proxy for this url.
        LOG(LS_INFO) << "No proxy detected for " << url;
      }
      pWHCH(hWinHttp);
    }
  } else {
    LOG(LS_ERROR) << "Failed loading WinHTTP functions.";
    success = false;
  }
  FreeLibrary(winhttp_handle);
  return success;
}

#if 0  // Below functions currently not used.

bool GetJsProxySettings(const char* url, ProxyInfo* proxy) {
  Url<char> purl(url);
  bool success = false;

  if (HMODULE hModJS = LoadLibrary(_T("jsproxy.dll"))) {
    pfnInternetGetProxyInfo pIGPI =
        reinterpret_cast<pfnInternetGetProxyInfo>(
            GetProcAddress(hModJS, "InternetGetProxyInfo"));
    if (pIGPI) {
      char proxy[256], host[256];
      memset(proxy, 0, sizeof(proxy));
      char * ptr = proxy;
      DWORD proxylen = sizeof(proxy);
      std::string surl = Utf8String(url);
      DWORD hostlen = _snprintf(host, sizeof(host), "http%s://%S",
                                purl.secure() ? "s" : "", purl.server());
      if (pIGPI(surl.data(), surl.size(), host, hostlen, &ptr, &proxylen)) {
        LOG(INFO) << "Proxy: " << proxy;
      } else {
        LOG_GLE(INFO) << "InternetGetProxyInfo";
      }
    }
    FreeLibrary(hModJS);
  }
  return success;
}

bool GetWmProxySettings(const char* url, ProxyInfo* proxy) {
  Url<char> purl(url);
  bool success = false;

  INSNetSourceCreator * nsc = 0;
  HRESULT hr = CoCreateInstance(CLSID_ClientNetManager, 0, CLSCTX_ALL,
                                IID_INSNetSourceCreator, (LPVOID *) &nsc);
  if (SUCCEEDED(hr)) {
    if (SUCCEEDED(hr = nsc->Initialize())) {
      VARIANT dispatch;
      VariantInit(&dispatch);
      if (SUCCEEDED(hr = nsc->GetNetSourceAdminInterface(L"http", &dispatch))) {
        IWMSInternalAdminNetSource * ians = 0;
        if (SUCCEEDED(hr = dispatch.pdispVal->QueryInterface(
                IID_IWMSInternalAdminNetSource, (LPVOID *) &ians))) {
          _bstr_t host(purl.server());
          BSTR proxy = 0;
          BOOL bProxyEnabled = FALSE;
          DWORD port, context = 0;
          if (SUCCEEDED(hr = ians->FindProxyForURL(
                  L"http", host, &bProxyEnabled, &proxy, &port, &context))) {
            success = true;
            if (bProxyEnabled) {
              _bstr_t sproxy = proxy;
              proxy->ptype = PT_HTTPS;
              proxy->host = sproxy;
              proxy->port = port;
            }
          }
          SysFreeString(proxy);
          if (FAILED(hr = ians->ShutdownProxyContext(context))) {
            LOG(LS_INFO) << "IWMSInternalAdminNetSource::ShutdownProxyContext"
                         << "failed: " << hr;
          }
          ians->Release();
        }
      }
      VariantClear(&dispatch);
      if (FAILED(hr = nsc->Shutdown())) {
        LOG(LS_INFO) << "INSNetSourceCreator::Shutdown failed: " << hr;
      }
    }
    nsc->Release();
  }
  return success;
}

bool GetIePerConnectionProxySettings(const char* url, ProxyInfo* proxy) {
  Url<char> purl(url);
  bool success = false;

  INTERNET_PER_CONN_OPTION_LIST list;
  INTERNET_PER_CONN_OPTION options[3];
  memset(&list, 0, sizeof(list));
  memset(&options, 0, sizeof(options));

  list.dwSize = sizeof(list);
  list.dwOptionCount = 3;
  list.pOptions = options;
  options[0].dwOption = INTERNET_PER_CONN_FLAGS;
  options[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
  options[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS;
  DWORD dwSize = sizeof(list);

  if (!InternetQueryOption(0, INTERNET_OPTION_PER_CONNECTION_OPTION, &list,
                           &dwSize)) {
    LOG(LS_INFO) << "InternetQueryOption failed: " << GetLastError();
  } else if ((options[0].Value.dwValue & PROXY_TYPE_PROXY) != 0) {
    success = true;
    if (!ProxyListMatch(purl, nonnull(options[2].Value.pszValue), _T(';'))) {
      ParseProxy(nonnull(options[1].Value.pszValue), proxy);
    }
  } else if ((options[0].Value.dwValue & PROXY_TYPE_DIRECT) != 0) {
    success = true;
  } else {
    LOG(LS_INFO) << "unknown internet access type: "
                 << options[0].Value.dwValue;
  }
  if (options[1].Value.pszValue) {
    GlobalFree(options[1].Value.pszValue);
  }
  if (options[2].Value.pszValue) {
    GlobalFree(options[2].Value.pszValue);
  }
  return success;
}

#endif  // 0

// Uses the InternetQueryOption function to retrieve proxy settings
// from the registry. This will only give us the 'static' settings,
// ie, not any information about auto config etc.
bool GetIeLanProxySettings(const char* url, ProxyInfo* proxy) {
  Url<char> purl(url);
  bool success = false;

  wchar_t buffer[1024];
  memset(buffer, 0, sizeof(buffer));
  INTERNET_PROXY_INFO * info = reinterpret_cast<INTERNET_PROXY_INFO *>(buffer);
  DWORD dwSize = sizeof(buffer);

  if (!InternetQueryOption(0, INTERNET_OPTION_PROXY, info, &dwSize)) {
    LOG(LS_INFO) << "InternetQueryOption failed: " << GetLastError();
  } else if (info->dwAccessType == INTERNET_OPEN_TYPE_DIRECT) {
    success = true;
  } else if (info->dwAccessType == INTERNET_OPEN_TYPE_PROXY) {
    success = true;
    if (!ProxyListMatch(purl, nonnull(reinterpret_cast<const char*>(
            info->lpszProxyBypass)), ' ')) {
      ParseProxy(nonnull(reinterpret_cast<const char*>(info->lpszProxy)),
                 proxy);
    }
  } else {
    LOG(LS_INFO) << "unknown internet access type: " << info->dwAccessType;
  }
  return success;
}

bool GetIeProxySettings(const char* agent, const char* url, ProxyInfo* proxy) {
  bool success = GetWinHttpProxySettings(url, proxy);
  if (!success) {
    // TODO: Should always call this if no proxy were detected by
    // GetWinHttpProxySettings?
    // WinHttp failed. Try using the InternetOptionQuery method instead.
    return GetIeLanProxySettings(url, proxy);
  }
  return true;
}

#endif  // WEBRTC_WIN

#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)  // WEBRTC_MAC && !defined(WEBRTC_IOS) specific implementation for reading system wide
            // proxy settings.

bool p_getProxyInfoForTypeFromDictWithKeys(ProxyInfo* proxy,
                                           ProxyType type,
                                           const CFDictionaryRef proxyDict,
                                           const CFStringRef enabledKey,
                                           const CFStringRef hostKey,
                                           const CFStringRef portKey) {
  // whether or not we set up the proxy info.
  bool result = false;

  // we use this as a scratch variable for determining if operations
  // succeeded.
  bool converted = false;

  // the data we need to construct the SocketAddress for the proxy.
  std::string hostname;
  int port;

  if ((proxyDict != NULL) &&
      (CFGetTypeID(proxyDict) == CFDictionaryGetTypeID())) {
    // CoreFoundation stuff that we'll have to get from
    // the dictionaries and interpret or convert into more usable formats.
    CFNumberRef enabledCFNum;
    CFNumberRef portCFNum;
    CFStringRef hostCFStr;

    enabledCFNum = (CFNumberRef)CFDictionaryGetValue(proxyDict, enabledKey);

    if (p_isCFNumberTrue(enabledCFNum)) {
      // let's see if we can get the address and port.
      hostCFStr = (CFStringRef)CFDictionaryGetValue(proxyDict, hostKey);
      converted = p_convertHostCFStringRefToCPPString(hostCFStr, hostname);
      if (converted) {
        portCFNum = (CFNumberRef)CFDictionaryGetValue(proxyDict, portKey);
        converted = p_convertCFNumberToInt(portCFNum, &port);
        if (converted) {
          // we have something enabled, with a hostname and a port.
          // That's sufficient to set up the proxy info.
          proxy->type = type;
          proxy->address.SetIP(hostname);
          proxy->address.SetPort(port);
          result = true;
        }
      }
    }
  }

  return result;
}

// Looks for proxy information in the given dictionary,
// return true if it found sufficient information to define one,
// false otherwise.  This is guaranteed to not change the values in proxy
// unless a full-fledged proxy description was discovered in the dictionary.
// However, at the present time this does not support username or password.
// Checks first for a SOCKS proxy, then for HTTPS, then HTTP.
bool GetMacProxySettingsFromDictionary(ProxyInfo* proxy,
                                       const CFDictionaryRef proxyDict) {
  // the function result.
  bool gotProxy = false;


  // first we see if there's a SOCKS proxy in place.
  gotProxy = p_getProxyInfoForTypeFromDictWithKeys(proxy,
                                                   PROXY_SOCKS5,
                                                   proxyDict,
                                                   kSCPropNetProxiesSOCKSEnable,
                                                   kSCPropNetProxiesSOCKSProxy,
                                                   kSCPropNetProxiesSOCKSPort);

  if (!gotProxy) {
    // okay, no SOCKS proxy, let's look for https.
    gotProxy = p_getProxyInfoForTypeFromDictWithKeys(proxy,
                                               PROXY_HTTPS,
                                               proxyDict,
                                               kSCPropNetProxiesHTTPSEnable,
                                               kSCPropNetProxiesHTTPSProxy,
                                               kSCPropNetProxiesHTTPSPort);
    if (!gotProxy) {
      // Finally, try HTTP proxy. Note that flute doesn't
      // differentiate between HTTPS and HTTP, hence we are using the
      // same flute type here, ie. PROXY_HTTPS.
      gotProxy = p_getProxyInfoForTypeFromDictWithKeys(
          proxy, PROXY_HTTPS, proxyDict, kSCPropNetProxiesHTTPEnable,
          kSCPropNetProxiesHTTPProxy, kSCPropNetProxiesHTTPPort);
    }
  }
  return gotProxy;
}

// TODO(hughv) Update keychain functions. They work on 10.8, but are depricated.
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
bool p_putPasswordInProxyInfo(ProxyInfo* proxy) {
  bool result = true;  // by default we assume we're good.
  // for all we know there isn't any password.  We'll set to false
  // if we find a problem.

  // Ask the keychain for an internet password search for the given protocol.
  OSStatus oss = 0;
  SecKeychainAttributeList attrList;
  attrList.count = 3;
  SecKeychainAttribute attributes[3];
  attrList.attr = attributes;

  attributes[0].tag = kSecProtocolItemAttr;
  attributes[0].length = sizeof(SecProtocolType);
  SecProtocolType protocol;
  switch (proxy->type) {
    case PROXY_HTTPS :
      protocol = kSecProtocolTypeHTTPS;
      break;
    case PROXY_SOCKS5 :
      protocol = kSecProtocolTypeSOCKS;
      break;
    default :
      LOG(LS_ERROR) << "asked for proxy password for unknown proxy type.";
      result = false;
      break;
  }
  attributes[0].data = &protocol;

  UInt32 port = proxy->address.port();
  attributes[1].tag = kSecPortItemAttr;
  attributes[1].length = sizeof(UInt32);
  attributes[1].data = &port;

  std::string ip = proxy->address.ipaddr().ToString();
  attributes[2].tag = kSecServerItemAttr;
  attributes[2].length = ip.length();
  attributes[2].data = const_cast<char*>(ip.c_str());

  if (result) {
    LOG(LS_INFO) << "trying to get proxy username/password";
    SecKeychainSearchRef sref;
    oss = SecKeychainSearchCreateFromAttributes(NULL,
                                                kSecInternetPasswordItemClass,
                                                &attrList, &sref);
    if (0 == oss) {
      LOG(LS_INFO) << "SecKeychainSearchCreateFromAttributes was good";
      // Get the first item, if there is one.
      SecKeychainItemRef iref;
      oss = SecKeychainSearchCopyNext(sref, &iref);
      if (0 == oss) {
        LOG(LS_INFO) << "...looks like we have the username/password data";
        // If there is, get the username and the password.

        SecKeychainAttributeInfo attribsToGet;
        attribsToGet.count = 1;
        UInt32 tag = kSecAccountItemAttr;
        UInt32 format = CSSM_DB_ATTRIBUTE_FORMAT_STRING;
        void *data;
        UInt32 length;
        SecKeychainAttributeList *localList;

        attribsToGet.tag = &tag;
        attribsToGet.format = &format;
        OSStatus copyres = SecKeychainItemCopyAttributesAndData(iref,
                                                                &attribsToGet,
                                                                NULL,
                                                                &localList,
                                                                &length,
                                                                &data);
        if (0 == copyres) {
          LOG(LS_INFO) << "...and we can pull it out.";
          // now, we know from experimentation (sadly not from docs)
          // that the username is in the local attribute list,
          // and the password in the data,
          // both without null termination but with info on their length.
          // grab the password from the data.
          std::string password;
          password.append(static_cast<const char*>(data), length);

          // make the password into a CryptString
          // huh, at the time of writing, you can't.
          // so we'll skip that for now and come back to it later.

          // now put the username in the proxy.
          if (1 <= localList->attr->length) {
            proxy->username.append(
                static_cast<const char*>(localList->attr->data),
                localList->attr->length);
            LOG(LS_INFO) << "username is " << proxy->username;
          } else {
            LOG(LS_ERROR) << "got keychain entry with no username";
            result = false;
          }
        } else {
          LOG(LS_ERROR) << "couldn't copy info from keychain.";
          result = false;
        }
        SecKeychainItemFreeAttributesAndData(localList, data);
      } else if (errSecItemNotFound == oss) {
        LOG(LS_INFO) << "...username/password info not found";
      } else {
        // oooh, neither 0 nor itemNotFound.
        LOG(LS_ERROR) << "Couldn't get keychain information, error code" << oss;
        result = false;
      }
    } else if (errSecItemNotFound == oss) {  // noop
    } else {
      // oooh, neither 0 nor itemNotFound.
      LOG(LS_ERROR) << "Couldn't get keychain information, error code" << oss;
      result = false;
    }
  }

  return result;
}

bool GetMacProxySettings(ProxyInfo* proxy) {
  // based on the Apple Technical Q&A QA1234
  // http://developer.apple.com/qa/qa2001/qa1234.html
  CFDictionaryRef proxyDict = SCDynamicStoreCopyProxies(NULL);
  bool result = false;

  if (proxyDict != NULL) {
    // sending it off to another function makes it easier to unit test
    // since we can make our own dictionary to hand to that function.
    result = GetMacProxySettingsFromDictionary(proxy, proxyDict);

    if (result) {
      result = p_putPasswordInProxyInfo(proxy);
    }

    CFRelease(proxyDict);
  } else {
    LOG(LS_ERROR) << "SCDynamicStoreCopyProxies failed";
  }

  return result;
}
#endif  // WEBRTC_MAC && !defined(WEBRTC_IOS)

#ifdef WEBRTC_IOS
// iOS has only http proxy
bool GetiOSProxySettings(ProxyInfo* proxy) {

  bool result = false;

  CFDictionaryRef proxy_dict = CFNetworkCopySystemProxySettings();
  if (!proxy_dict) {
    LOG(LS_ERROR) << "CFNetworkCopySystemProxySettings failed";
    return false;
  }

  CFNumberRef proxiesHTTPEnable = (CFNumberRef)CFDictionaryGetValue(
    proxy_dict, kCFNetworkProxiesHTTPEnable);
  if (!p_isCFNumberTrue(proxiesHTTPEnable)) {
    CFRelease(proxy_dict);
    return false;
  }

  CFStringRef proxy_address = (CFStringRef)CFDictionaryGetValue(
    proxy_dict, kCFNetworkProxiesHTTPProxy);
  CFNumberRef proxy_port = (CFNumberRef)CFDictionaryGetValue(
    proxy_dict, kCFNetworkProxiesHTTPPort);

  // the data we need to construct the SocketAddress for the proxy.
  std::string hostname;
  int port;
  if (p_convertHostCFStringRefToCPPString(proxy_address, hostname) &&
      p_convertCFNumberToInt(proxy_port, &port)) {
      // We have something enabled, with a hostname and a port.
      // That's sufficient to set up the proxy info.
      // Finally, try HTTP proxy. Note that flute doesn't
      // differentiate between HTTPS and HTTP, hence we are using the
      // same flute type here, ie. PROXY_HTTPS.
      proxy->type = PROXY_HTTPS;

      proxy->address.SetIP(hostname);
      proxy->address.SetPort(port);
      result = true;
  }

  CFRelease(proxy_dict);

  return result;
}
#endif // WEBRTC_IOS

bool AutoDetectProxySettings(const char* agent, const char* url,
                             ProxyInfo* proxy) {
#if defined(WEBRTC_WIN)
  return WinHttpAutoDetectProxyForUrl(agent, url, proxy);
#else
  LOG(LS_WARNING) << "Proxy auto-detection not implemented for this platform";
  return false;
#endif
}

bool GetSystemDefaultProxySettings(const char* agent, const char* url,
                                   ProxyInfo* proxy) {
#if defined(WEBRTC_WIN)
  return GetIeProxySettings(agent, url, proxy);
#elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
  return GetMacProxySettings(proxy);
#elif defined(WEBRTC_IOS)
  return GetiOSProxySettings(proxy);
#else
  // TODO: Get System settings if browser is not firefox.
  return GetFirefoxProxySettings(url, proxy);
#endif
}

bool GetProxySettingsForUrl(const char* agent, const char* url,
                            ProxyInfo* proxy, bool long_operation) {
  UserAgent a = GetAgent(agent);
  bool result;
  switch (a) {
    case UA_FIREFOX: {
      result = GetFirefoxProxySettings(url, proxy);
      break;
    }
#if defined(WEBRTC_WIN)
    case UA_INTERNETEXPLORER:
      result = GetIeProxySettings(agent, url, proxy);
      break;
    case UA_UNKNOWN:
      // Agent not defined, check default browser.
      if (IsDefaultBrowserFirefox()) {
        result = GetFirefoxProxySettings(url, proxy);
      } else {
        result = GetIeProxySettings(agent, url, proxy);
      }
      break;
#endif  // WEBRTC_WIN
    default:
      result = GetSystemDefaultProxySettings(agent, url, proxy);
      break;
  }

  // TODO: Consider using the 'long_operation' parameter to
  // decide whether to do the auto detection.
  if (result && (proxy->autodetect ||
                 !proxy->autoconfig_url.empty())) {
    // Use WinHTTP to auto detect proxy for us.
    result = AutoDetectProxySettings(agent, url, proxy);
    if (!result) {
      // Either auto detection is not supported or we simply didn't
      // find any proxy, reset type.
      proxy->type = rtc::PROXY_NONE;
    }
  }
  return result;
}

}  // namespace rtc
