⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 proxydetect.cc

📁 本人收集整理的一份c/c++跨平台网络库
💻 CC
📖 第 1 页 / 共 2 页
字号:
// TODO: Abstract this better for cross-platformability#ifdef _WINDOWS#include "win32.h"#include <shlobj.h>#endif#include "httpcommon.h"#include "httpcommon-inl.h"#include "proxydetect.h"#include "stringutils.h"#include "basicdefs.h"#if _WINDOWS#define _TRY_FIREFOX 1#define _TRY_WINHTTP 1#define _TRY_JSPROXY 0#define _TRY_WM_FINDPROXY 0#define _TRY_IE_LAN_SETTINGS 1#endif // _WINDOWS#if _TRY_WINHTTP//#include <winhttp.h>// Note: From winhttp.hconst 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_JSPROXYextern "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_SETTINGSusing namespace utils_base;//////////////////////////////////////////////////////////////////////// Utility Functions//////////////////////////////////////////////////////////////////////#ifdef _WINDOWS#ifdef _UNICODEtypedef std::wstring tstring;std::string Utf8String(const tstring& str) { return ToUtf8(str); }#else  // !_UNICODEtypedef std::string tstring;std::string Utf8String(const tstring& str) { return str; }#endif  // !_UNICODE#endif  // _WINDOWS//////////////////////////////////////////////////////////////////////// GetProxySettingsForUrl//////////////////////////////////////////////////////////////////////bool WildMatch(const char * target, const char * pattern) {  while (*pattern) {    if (*pattern == '*') {      if (!*++pattern) {        return true;      }      while (*target) {        if ((toupper(*pattern) == toupper(*target)) && WildMatch(target + 1, pattern + 1)) {          return true;        }        ++target;      }      return false;    } else {      if (toupper(*pattern) != toupper(*target)) {        return false;      }      ++target;      ++pattern;    }  }  return !*target;}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 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 mask = (m == 0) ? 0 : (~0UL) << (32 - m);    SocketAddress addr(url.server());    return !addr.IsUnresolved() && ((addr.ip() & mask) == (ip & mask));  }  // .foo.com  if (*item == '.') {    size_t hostlen = url.server().length();    return (hostlen > len)      && (stricmp(url.server().c_str() + (hostlen - len), item) == 0);  }  // localhost or www.*.com  if (!WildMatch(url.server().c_str(), item))    return false;  return true;}bool ProxyListMatch(const Url<char>& url, const std::string& slist, char sep) {  const size_t BUFSIZE = 256;  char buffer[BUFSIZE];  const char* list = slist.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[4] = { 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 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 (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>(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((int)port);    }  }  return (proxy.type != PROXY_NONE);}#if _WINDOWSbool IsDefaultBrowserFirefox() {  HKEY key;  LONG result = RegOpenKeyEx(HKEY_CLASSES_ROOT, L"http\\shell\\open\\command",                             0, KEY_READ, &key);  if (ERROR_SUCCESS != result)    return false;  wchar_t* value = NULL;  DWORD size, type;  result = RegQueryValueEx(key, L"", 0, &type, NULL, &size);  if (REG_SZ != type) {    result = ERROR_ACCESS_DENIED;  // Any error is fine  } else if (ERROR_SUCCESS == result) {    value = new wchar_t[size+1];    BYTE* buffer = reinterpret_cast<BYTE*>(value);    result = RegQueryValueEx(key, L"", 0, &type, buffer, &size);  }  RegCloseKey(key);  bool success = false;  if (ERROR_SUCCESS == result) {    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;  return success;}#endif#if _TRY_FIREFOX#define USE_FIREFOX_PROFILES_INI 1bool GetDefaultFirefoxProfile(std::wstring* profile) {  ASSERT(NULL != profile);  wchar_t path[MAX_PATH];  if (SHGetFolderPath(0, CSIDL_APPDATA, 0, SHGFP_TYPE_CURRENT, path) != S_OK)    return false;  std::wstring profile_root(path);  profile_root.append(L"\\Mozilla\\Firefox\\");#if USE_FIREFOX_PROFILES_INI  std::wstring tmp(profile_root);  tmp.append(L"profiles.ini");  FILE * fp = _wfopen(tmp.c_str(), L"rb");  if (!fp)    return false;  // [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  std::wstring candidate;  bool relative = true;  char buffer[1024];  while (fgets(buffer, sizeof(buffer), fp)) {    size_t len = strlen(buffer);    while ((len > 0) && isspace(buffer[len-1]))      buffer[--len] = 0;    if (buffer[0] == '[') {      relative = true;      candidate.clear();    } else if (strnicmp(buffer, "IsRelative=", 11) == 0) {      relative = (buffer[11] != '0');    } else if (strnicmp(buffer, "Path=", 5) == 0) {      if (relative) {        candidate = profile_root;      } else {        candidate.clear();      }      candidate.append(ToUtf16(buffer + 5));      candidate.append(L"\\");    } else if (strnicmp(buffer, "Default=", 8) == 0) {      if ((buffer[8] != '0') && !candidate.empty()) {        break;      }    }  }  fclose(fp);  if (candidate.empty())    return false;  *profile = candidate;#else // !USE_FIREFOX_PROFILES_INI  std::wstring tmp(profile_root);  tmp.append(L"Profiles\\*.default");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -