HINTERNET WinHTTPSession::setup(const Request & request, LPCWSTR method) { platform::WideString wurl(request.url()); URL_COMPONENTS url; ZeroMemory(&url, sizeof(url)); url.dwStructSize = sizeof(url); url.dwSchemeLength = url.dwHostNameLength = url.dwUrlPathLength = DWORD(-1); if(WinHttpCrackUrl(wurl, 0, 0, &url) != TRUE) { throw new Response("Invalid URL: \"" + request.url() + "\""); } DWORD flags = 0; if(url.nScheme == INTERNET_SCHEME_HTTPS) { flags |= WINHTTP_FLAG_SECURE; } else if(url.nScheme != INTERNET_SCHEME_HTTP) { throw new Response("Unsupported protocol"); } if(m_scheme != url.nScheme || m_port != url.nPort || m_host.compare(0, m_host.length(), url.lpszHostName, url.dwHostNameLength) != 0) { if(m_connection) { WinHttpCloseHandle(m_connection); } m_scheme = url.nScheme; m_host.assign(url.lpszHostName, url.dwHostNameLength); m_port = url.nPort; m_connection = WinHttpConnect(m_session, m_host.c_str(), m_port, 0); } if(!m_connection) { throw new Response("Could not create connection object: " + errorString()); } LPCWSTR resource = url.dwUrlPathLength ? url.lpszUrlPath : L"/"; LPCWSTR accept[] = { L"*/*", NULL }; HINTERNET wrequest = WinHttpOpenRequest(m_connection, method, resource, NULL, WINHTTP_NO_REFERER, accept, flags); if(!wrequest) { throw new Response("Could not create request object: " + errorString()); } if(request.followRedirects()) { WinHttpSetStatusCallback(wrequest, statusCallback, WINHTTP_CALLBACK_FLAG_REDIRECT, 0); } else { ULONG disable = WINHTTP_DISABLE_REDIRECTS; WinHttpSetOption(wrequest, WINHTTP_OPTION_DISABLE_FEATURE, &disable, sizeof(disable)); } return wrequest; }
void openUrl(string url) { #ifdef _WIN32 wstring wurl(url.begin(), url.end()); ShellExecute(NULL, L"open", wurl.c_str(), NULL, NULL, SW_SHOWDEFAULT); #endif #ifdef __APPLE__ CFURLRef urlref = CFURLCreateWithBytes(NULL, (UInt8*)url.c_str(), url.length(), kCFStringEncodingASCII, NULL); int cnt = 0; while (LSOpenCFURLRef(urlref,0) != 0) { usleep(10000); cnt++; if (cnt > 100) break; } CFRelease(urlref); #endif }
bool Proxy::GetProxyForUrl(const String &url, Address &addr) { if(HttpProxy == "none") return false; if(!HttpProxy.empty() && HttpProxy != "auto") { addr.fromString(HttpProxy); return true; } #ifdef WINDOWS typedef LPVOID HINTERNET; typedef struct { DWORD dwAccessType; LPWSTR lpszProxy; LPWSTR lpszProxyBypass; } WINHTTP_PROXY_INFO; typedef struct { BOOL fAutoDetect; LPWSTR lpszAutoConfigUrl; LPWSTR lpszProxy; LPWSTR lpszProxyBypass; } WINHTTP_CURRENT_USER_IE_PROXY_CONFIG; typedef struct { DWORD dwFlags; DWORD dwAutoDetectFlags; LPCWSTR lpszAutoConfigUrl; LPVOID lpvReserved; DWORD dwReserved; BOOL fAutoLogonIfChallenged; } WINHTTP_AUTOPROXY_OPTIONS; #define WINHTTP_ACCESS_TYPE_DEFAULT_PROXY 0 #define WINHTTP_ACCESS_TYPE_NO_PROXY 1 #define WINHTTP_ACCESS_TYPE_NAMED_PROXY 3 #define WINHTTP_AUTOPROXY_AUTO_DETECT 0x00000001 #define WINHTTP_AUTOPROXY_CONFIG_URL 0x00000002 #define WINHTTP_AUTO_DETECT_TYPE_DHCP 0x00000001 #define WINHTTP_AUTO_DETECT_TYPE_DNS_A 0x00000002 #define WINHTTP_ERROR_BASE 12000 #define ERROR_WINHTTP_LOGIN_FAILURE (WINHTTP_ERROR_BASE + 15) #define ERROR_WINHTTP_AUTODETECTION_FAILED (WINHTTP_ERROR_BASE + 180) typedef HINTERNET (WINAPI *WINHTTPOPEN)(LPCWSTR pwszUserAgent, DWORD dwAccessType, LPCWSTR pwszProxyName, LPCWSTR pwszProxyBypass, DWORD dwFlags); typedef BOOL (WINAPI *WINHTTPGETPROXYFORURL)(HINTERNET hSession, LPCWSTR lpcwszUrl, WINHTTP_AUTOPROXY_OPTIONS *pAutoProxyOptions, WINHTTP_PROXY_INFO *pProxyInfo); typedef BOOL (WINAPI *WINHTTPGETDEFAULTPROXYCONFIGURATION)(WINHTTP_PROXY_INFO *pProxyInfo); typedef BOOL (WINAPI *WINHTTPGETIEPROXYCONFIGFORCURRENTUSER)(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG *pProxyConfig); typedef BOOL (WINAPI *WINHTTPCLOSEHANDLE)(HINTERNET hInternet); static HMODULE hWinHttp = NULL; static WINHTTPOPEN WinHttpOpen; static WINHTTPGETPROXYFORURL WinHttpGetProxyForUrl; static WINHTTPGETDEFAULTPROXYCONFIGURATION WinHttpGetDefaultProxyConfiguration; static WINHTTPGETIEPROXYCONFIGFORCURRENTUSER WinHttpGetIEProxyConfigForCurrentUser; static WINHTTPCLOSEHANDLE WinHttpCloseHandle; if(!hWinHttp) { hWinHttp = LoadLibrary("winhttp.dll"); if(!hWinHttp) return false; WinHttpOpen = (WINHTTPOPEN) GetProcAddress(hWinHttp, "WinHttpOpen"); WinHttpGetProxyForUrl = (WINHTTPGETPROXYFORURL) GetProcAddress(hWinHttp, "WinHttpGetProxyForUrl"); WinHttpGetDefaultProxyConfiguration = (WINHTTPGETDEFAULTPROXYCONFIGURATION) GetProcAddress(hWinHttp, "WinHttpGetDefaultProxyConfiguration"); WinHttpGetIEProxyConfigForCurrentUser = (WINHTTPGETIEPROXYCONFIGFORCURRENTUSER) GetProcAddress(hWinHttp, "WinHttpGetIEProxyConfigForCurrentUser"); WinHttpCloseHandle = (WINHTTPCLOSEHANDLE) GetProcAddress(hWinHttp, "WinHttpCloseHandle"); } bool hasProxy = false; std::string ua(Http::UserAgent); std::wstring wua(ua.begin(), ua.end()); HINTERNET hSession = WinHttpOpen(wua.c_str(), WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, NULL, NULL, 0); if(hSession) { WINHTTP_CURRENT_USER_IE_PROXY_CONFIG userProxyConfig; bool hasUserProxyConfig = (WinHttpGetIEProxyConfigForCurrentUser(&userProxyConfig) == TRUE); if(hasUserProxyConfig && !userProxyConfig.fAutoDetect && userProxyConfig.lpszProxy) { hasProxy = ParseWinHttpProxy(userProxyConfig.lpszProxy, addr); } else { WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions; std::memset(&autoProxyOptions, 0, sizeof(autoProxyOptions)); autoProxyOptions.fAutoLogonIfChallenged = TRUE; if(hasUserProxyConfig) autoProxyOptions.lpszAutoConfigUrl = userProxyConfig.lpszAutoConfigUrl; else autoProxyOptions.lpszAutoConfigUrl = NULL; if(autoProxyOptions.lpszAutoConfigUrl) { autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT; autoProxyOptions.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP|WINHTTP_AUTO_DETECT_TYPE_DNS_A; } else { autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL; autoProxyOptions.dwAutoDetectFlags = 0; } WINHTTP_PROXY_INFO proxyInfo; std::wstring wurl(url.begin(), url.end()); if(WinHttpGetProxyForUrl(hSession, wurl.c_str(), &autoProxyOptions, &proxyInfo)) { if(proxyInfo.lpszProxy && proxyInfo.dwAccessType == WINHTTP_ACCESS_TYPE_NAMED_PROXY) hasProxy = ParseWinHttpProxy(proxyInfo.lpszProxy, addr); if(proxyInfo.lpszProxy) GlobalFree(proxyInfo.lpszProxy); if(proxyInfo.lpszProxyBypass) GlobalFree(proxyInfo.lpszProxyBypass); } else if(WinHttpGetDefaultProxyConfiguration(&proxyInfo)) { if(proxyInfo.lpszProxy && proxyInfo.dwAccessType == WINHTTP_ACCESS_TYPE_NAMED_PROXY) hasProxy = ParseWinHttpProxy(proxyInfo.lpszProxy, addr); if(proxyInfo.lpszProxy) GlobalFree(proxyInfo.lpszProxy); if(proxyInfo.lpszProxyBypass) GlobalFree(proxyInfo.lpszProxyBypass); } } if(hasUserProxyConfig) { if(userProxyConfig.lpszProxy) GlobalFree(userProxyConfig.lpszProxy); if(userProxyConfig.lpszProxyBypass) GlobalFree(userProxyConfig.lpszProxyBypass); if(userProxyConfig.lpszAutoConfigUrl) GlobalFree(userProxyConfig.lpszAutoConfigUrl); } WinHttpCloseHandle(hSession); } return hasProxy; #else // TODO return false; #endif }