/*
 *  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 "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");
  scoped_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) {
  scoped_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);
    }

    // We created the dictionary with something that had the
    // word 'copy' in it, so we have to release it, according
    // to the Carbon memory management standards.
    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;
  }

  // We created the dictionary with something that had the
  // word 'copy' in it, so we have to release it, according
  // to the Carbon memory management standards.
  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
