mirror of
https://github.com/chibicitiberiu/rainmeter-studio.git
synced 2024-02-24 04:33:31 +00:00
WebParser: Modified proxy handling
- Added new proxy setting switch: /auto, /none /auto: use IE setting /none: direct connection Example: ProxyServer=/none - Added global proxy setting. If proxy setting is defined in Rainmeter.data, use it as a global proxy. Default value is /auto. Example: [WebParser.dll] ProxyServer=example.net:8080 If ProxyServer= is not defined or is empty string in WebParser measure, use a global proxy. If an individual proxy setting is defined in WebParser measure, use it instead of a global proxy.
This commit is contained in:
parent
7e958bdc23
commit
82eb3ed03f
@ -7,7 +7,7 @@
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,13,0,0
|
||||
FILEVERSION 1,14,0,0
|
||||
PRODUCTVERSION PRODUCTVER
|
||||
FILEFLAGSMASK 0x17L
|
||||
#ifdef _DEBUG
|
||||
@ -23,7 +23,7 @@ VS_VERSION_INFO VERSIONINFO
|
||||
{
|
||||
BLOCK "040904E4"
|
||||
{
|
||||
VALUE "FileVersion", "1.13.0.0"
|
||||
VALUE "FileVersion", "1.14.0.0"
|
||||
VALUE "LegalCopyright", "© 2010 - Rainy"
|
||||
VALUE "ProductName", "Rainmeter"
|
||||
#ifdef _WIN64
|
||||
|
@ -29,6 +29,175 @@
|
||||
#include "../../Library/DisableThreadLibraryCalls.h" // contains DllMain entry point
|
||||
#include "../API/RainmeterAPI.h"
|
||||
|
||||
void ShowError(int lineNumber, WCHAR* errorMsg = NULL);
|
||||
|
||||
class ProxyCachePool
|
||||
{
|
||||
public:
|
||||
ProxyCachePool(LPCWSTR globalProxyName = NULL) :
|
||||
m_GlobalProxyName((globalProxyName && *globalProxyName) ? globalProxyName : L"/auto")
|
||||
{
|
||||
m_GlobalProxyCache = new ProxyCache(CreateProxy(m_GlobalProxyName.c_str()), true);
|
||||
|
||||
_wcslwr(&m_GlobalProxyName[0]);
|
||||
m_CacheMap[m_GlobalProxyName] = m_GlobalProxyCache;
|
||||
//DebugLog(L"* ADD-GLOBAL: key=%s, handle=0x%p, ref=new", m_GlobalProxyName.c_str(), m_GlobalProxyCache->GetCache());
|
||||
}
|
||||
|
||||
~ProxyCachePool()
|
||||
{
|
||||
for (auto iter = m_CacheMap.begin(); iter != m_CacheMap.end(); ++iter)
|
||||
{
|
||||
ProxyCache* cache = (*iter).second;
|
||||
//DebugLog(L"* FORCE-REMOVE: key=%s, global=%i, ref=%i", (*iter).first.c_str(), cache->IsGlobal(), cache->GetRef());
|
||||
delete cache;
|
||||
}
|
||||
}
|
||||
|
||||
HINTERNET GetCache(const std::wstring& proxyName)
|
||||
{
|
||||
ProxyCache* cache = NULL;
|
||||
|
||||
if (proxyName.empty())
|
||||
{
|
||||
// Use global proxy setting
|
||||
cache = m_GlobalProxyCache;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wstring key = proxyName;
|
||||
_wcslwr(&key[0]);
|
||||
|
||||
auto iter = m_CacheMap.find(key);
|
||||
if (iter != m_CacheMap.end())
|
||||
{
|
||||
cache = (*iter).second;
|
||||
}
|
||||
else // cache not found
|
||||
{
|
||||
// Create new proxy
|
||||
ProxyCache* cache = new ProxyCache(CreateProxy(proxyName.c_str()));
|
||||
m_CacheMap[key] = cache;
|
||||
//DebugLog(L"* ADD: key=%s, handle=0x%p, ref=new", key.c_str(), cache->GetCache());
|
||||
return cache->GetCache();
|
||||
}
|
||||
}
|
||||
|
||||
// Use proxy cache
|
||||
cache->AddRef();
|
||||
//DebugLog(L"* ADD-REF: key=%s, handle=0x%p, global=%i, ref=%i",
|
||||
// cache->IsGlobal() ? m_GlobalProxyName.c_str() : proxyName.c_str(), cache->GetCache(), cache->IsGlobal(), cache->GetRef());
|
||||
return cache->GetCache();
|
||||
}
|
||||
|
||||
void RemoveCache(const std::wstring& proxyName)
|
||||
{
|
||||
std::wstring key = proxyName.empty() ? m_GlobalProxyName : proxyName;
|
||||
|
||||
if (!proxyName.empty())
|
||||
{
|
||||
_wcslwr(&key[0]);
|
||||
}
|
||||
|
||||
auto iter = m_CacheMap.find(key);
|
||||
if (iter != m_CacheMap.end())
|
||||
{
|
||||
ProxyCache* cache = (*iter).second;
|
||||
cache->Release();
|
||||
//DebugLog(L"* REMOVE: key=%s, global=%i, ref=%i", key.c_str(), cache->IsGlobal(), cache->GetRef());
|
||||
|
||||
if (cache->IsInvalid())
|
||||
{
|
||||
//DebugLog(L"* EMPTY-ERASE: key=%s", key.c_str());
|
||||
m_CacheMap.erase(iter);
|
||||
delete cache;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
HINTERNET CreateProxy(LPCWSTR proxyName)
|
||||
{
|
||||
DWORD proxyType;
|
||||
LPCWSTR proxyServer;
|
||||
|
||||
if (_wcsicmp(proxyName, L"/auto") == 0)
|
||||
{
|
||||
proxyType = INTERNET_OPEN_TYPE_PRECONFIG;
|
||||
proxyServer = NULL;
|
||||
}
|
||||
else if (_wcsicmp(proxyName, L"/none") == 0)
|
||||
{
|
||||
proxyType = INTERNET_OPEN_TYPE_DIRECT;
|
||||
proxyServer = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
proxyType = INTERNET_OPEN_TYPE_PROXY;
|
||||
proxyServer = proxyName;
|
||||
}
|
||||
|
||||
HINTERNET handle = InternetOpen(L"Rainmeter WebParser plugin",
|
||||
proxyType,
|
||||
proxyServer,
|
||||
NULL,
|
||||
0);
|
||||
|
||||
if (handle)
|
||||
{
|
||||
WCHAR buffer[256];
|
||||
_snwprintf_s(buffer, _TRUNCATE, L"WebParser: ProxyServer=\"%s\" (type=%s, handle=0x%p)",
|
||||
proxyName,
|
||||
proxyType == INTERNET_OPEN_TYPE_PRECONFIG ? L"PRECONFIG" : proxyType == INTERNET_OPEN_TYPE_DIRECT ? L"DIRECT" : L"PROXY",
|
||||
handle);
|
||||
RmLog(LOG_DEBUG, buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowError(__LINE__);
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
class ProxyCache
|
||||
{
|
||||
public:
|
||||
ProxyCache(HINTERNET handle, bool isGlobal = false) : m_Handle(handle), m_IsGlobal(isGlobal), m_Ref(1) {}
|
||||
~ProxyCache() { Dispose(); }
|
||||
|
||||
void AddRef() { if (!IsInvalid()) { ++m_Ref; } }
|
||||
void Release() { if (m_Ref > 0) { --m_Ref; } if (IsInvalid()) { Dispose(); } }
|
||||
|
||||
bool IsGlobal() { return m_IsGlobal; }
|
||||
bool IsInvalid() { return (m_Ref <= 0 && !IsGlobal()); }
|
||||
//int GetRef() { return m_Ref; }
|
||||
HINTERNET GetCache() { return m_Handle; }
|
||||
|
||||
private:
|
||||
ProxyCache() {}
|
||||
ProxyCache(const ProxyCache& cache) {}
|
||||
|
||||
void Dispose() { if (m_Handle) { InternetCloseHandle(m_Handle); m_Handle = NULL; } }
|
||||
|
||||
HINTERNET m_Handle;
|
||||
bool m_IsGlobal;
|
||||
int m_Ref;
|
||||
};
|
||||
|
||||
std::unordered_map<std::wstring, ProxyCache*> m_CacheMap;
|
||||
ProxyCache* m_GlobalProxyCache;
|
||||
std::wstring m_GlobalProxyName;
|
||||
};
|
||||
|
||||
struct ProxySetting
|
||||
{
|
||||
std::wstring server;
|
||||
HINTERNET handle;
|
||||
|
||||
ProxySetting() : handle() {}
|
||||
};
|
||||
|
||||
struct MeasureData
|
||||
{
|
||||
std::wstring url;
|
||||
@ -42,6 +211,7 @@ struct MeasureData
|
||||
std::wstring debugFileLocation;
|
||||
LPCWSTR section;
|
||||
void* skin;
|
||||
ProxySetting proxy;
|
||||
HANDLE threadHandle;
|
||||
HANDLE dlThreadHandle;
|
||||
int codepage;
|
||||
@ -71,18 +241,17 @@ struct MeasureData
|
||||
}
|
||||
};
|
||||
|
||||
BYTE* DownloadUrl(std::wstring& url, DWORD* dwSize, bool forceReload);
|
||||
void ShowError(int lineNumber, WCHAR* errorMsg = NULL);
|
||||
BYTE* DownloadUrl(HINTERNET handle, std::wstring& url, DWORD* dwSize, bool forceReload);
|
||||
unsigned __stdcall NetworkThreadProc(void* pParam);
|
||||
unsigned __stdcall NetworkDownloadThreadProc(void* pParam);
|
||||
void ParseData(MeasureData* measure, LPCSTR parseData, DWORD dwSize);
|
||||
|
||||
CRITICAL_SECTION g_CriticalSection;
|
||||
ProxyCachePool* g_ProxyCachePool = NULL;
|
||||
UINT g_InstanceCount = 0;
|
||||
|
||||
static std::vector<MeasureData*> g_Measures;
|
||||
static bool g_Debug = false;
|
||||
static HINTERNET g_InternetHandle = NULL;
|
||||
|
||||
static std::unordered_map<std::wstring, WCHAR> g_CERs;
|
||||
|
||||
@ -535,6 +704,44 @@ void FillCharacterEntityReferences()
|
||||
//}
|
||||
}
|
||||
|
||||
void SetupGlobalProxySetting()
|
||||
{
|
||||
if (!g_ProxyCachePool)
|
||||
{
|
||||
WCHAR buffer[MAX_PATH] = {0};
|
||||
LPCWSTR file = RmGetSettingsFile();
|
||||
|
||||
GetPrivateProfileString(L"WebParser.dll", L"ProxyServer", NULL, buffer, MAX_PATH, file);
|
||||
g_ProxyCachePool = new ProxyCachePool(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void ClearGlobalProxySetting()
|
||||
{
|
||||
delete g_ProxyCachePool;
|
||||
g_ProxyCachePool = NULL;
|
||||
}
|
||||
|
||||
void SetupProxySetting(ProxySetting& setting, void* rm)
|
||||
{
|
||||
if (g_ProxyCachePool)
|
||||
{
|
||||
setting.server = RmReadString(rm, L"ProxyServer", L"");
|
||||
setting.handle = g_ProxyCachePool->GetCache(setting.server);
|
||||
}
|
||||
}
|
||||
|
||||
void ClearProxySetting(ProxySetting& setting)
|
||||
{
|
||||
if (g_ProxyCachePool)
|
||||
{
|
||||
g_ProxyCachePool->RemoveCache(setting.server);
|
||||
}
|
||||
|
||||
setting.handle = NULL;
|
||||
setting.server.clear();
|
||||
}
|
||||
|
||||
PLUGIN_EXPORT void Initialize(void** data, void* rm)
|
||||
{
|
||||
MeasureData* measure = new MeasureData;
|
||||
@ -548,18 +755,10 @@ PLUGIN_EXPORT void Initialize(void** data, void* rm)
|
||||
InitializeCriticalSection(&g_CriticalSection);
|
||||
FillCharacterEntityReferences();
|
||||
|
||||
LPCWSTR proxy = RmReadString(rm, L"ProxyServer", L"");
|
||||
g_InternetHandle = InternetOpen(L"Rainmeter WebParser plugin",
|
||||
*proxy ? INTERNET_OPEN_TYPE_PROXY : INTERNET_OPEN_TYPE_PRECONFIG,
|
||||
*proxy ? proxy : NULL,
|
||||
NULL,
|
||||
0);
|
||||
SetupGlobalProxySetting();
|
||||
}
|
||||
|
||||
if (g_InternetHandle == NULL)
|
||||
{
|
||||
ShowError(__LINE__);
|
||||
}
|
||||
}
|
||||
SetupProxySetting(measure->proxy, rm); // No support for DynamicVariables
|
||||
|
||||
++g_InstanceCount;
|
||||
}
|
||||
@ -699,7 +898,7 @@ unsigned __stdcall NetworkThreadProc(void* pParam)
|
||||
MeasureData* measure = (MeasureData*)pParam;
|
||||
DWORD dwSize = 0;
|
||||
|
||||
BYTE* data = DownloadUrl(measure->url, &dwSize, measure->forceReload);
|
||||
BYTE* data = DownloadUrl(measure->proxy.handle, measure->url, &dwSize, measure->forceReload);
|
||||
|
||||
if (data)
|
||||
{
|
||||
@ -1433,6 +1632,8 @@ PLUGIN_EXPORT void Finalize(void* data)
|
||||
}
|
||||
}
|
||||
|
||||
ClearProxySetting(measure->proxy);
|
||||
|
||||
delete measure;
|
||||
std::vector<MeasureData*>::iterator iter = std::find(g_Measures.begin(), g_Measures.end(), measure);
|
||||
g_Measures.erase(iter);
|
||||
@ -1441,11 +1642,7 @@ PLUGIN_EXPORT void Finalize(void* data)
|
||||
if (g_InstanceCount == 0)
|
||||
{
|
||||
// Last one, close all handles
|
||||
if (g_InternetHandle)
|
||||
{
|
||||
InternetCloseHandle(g_InternetHandle);
|
||||
g_InternetHandle = NULL;
|
||||
}
|
||||
ClearGlobalProxySetting();
|
||||
|
||||
g_CERs.clear();
|
||||
|
||||
@ -1458,7 +1655,7 @@ PLUGIN_EXPORT void Finalize(void* data)
|
||||
Downloads the given url and returns the webpage as dynamically allocated string.
|
||||
You need to delete the returned string after use!
|
||||
*/
|
||||
BYTE* DownloadUrl(std::wstring& url, DWORD* dwDataSize, bool forceReload)
|
||||
BYTE* DownloadUrl(HINTERNET handle, std::wstring& url, DWORD* dwDataSize, bool forceReload)
|
||||
{
|
||||
HINTERNET hUrlDump;
|
||||
DWORD dwSize;
|
||||
@ -1478,13 +1675,13 @@ BYTE* DownloadUrl(std::wstring& url, DWORD* dwDataSize, bool forceReload)
|
||||
flags = INTERNET_FLAG_RELOAD;
|
||||
}
|
||||
|
||||
hUrlDump = InternetOpenUrl(g_InternetHandle, url.c_str(), NULL, NULL, flags, 0);
|
||||
hUrlDump = InternetOpenUrl(handle, url.c_str(), NULL, NULL, flags, 0);
|
||||
if (hUrlDump == NULL)
|
||||
{
|
||||
if (_wcsnicmp(url.c_str(), L"file://", 7) == 0) // file scheme
|
||||
{
|
||||
std::string urlACP = ConvertWideToAscii(url.c_str());
|
||||
hUrlDump = InternetOpenUrlA(g_InternetHandle, urlACP.c_str(), NULL, NULL, flags, 0);
|
||||
hUrlDump = InternetOpenUrlA(handle, urlACP.c_str(), NULL, NULL, flags, 0);
|
||||
}
|
||||
|
||||
if (hUrlDump == NULL)
|
||||
@ -1647,7 +1844,7 @@ void ShowError(int lineNumber, WCHAR* errorMsg)
|
||||
|
||||
UINT GetPluginVersion()
|
||||
{
|
||||
return 1013;
|
||||
return 1014;
|
||||
}
|
||||
|
||||
LPCTSTR GetPluginAuthor()
|
||||
|
Loading…
Reference in New Issue
Block a user