/*
 *  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"
#include "webrtc/base/unixfilesystem.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"

#define _TRY_JSPROXY 0
#define _TRY_WM_FINDPROXY 0

#if defined(WEBRTC_WIN)
#define _TRY_WINHTTP 1
#define _TRY_IE_LAN_SETTINGS 1
#else
#define _TRY_WINHTTP 0
#define _TRY_IE_LAN_SETTINGS 0
#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)
  rtc::UnixFilesystem filesystem;
  filesystem.SetApplicationName("Firefox");
  bool result = filesystem.GetAppDataFolder(path, true);
  return result;
#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
