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
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,13,0,0
|
FILEVERSION 1,14,0,0
|
||||||
PRODUCTVERSION PRODUCTVER
|
PRODUCTVERSION PRODUCTVER
|
||||||
FILEFLAGSMASK 0x17L
|
FILEFLAGSMASK 0x17L
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
@ -23,7 +23,7 @@ VS_VERSION_INFO VERSIONINFO
|
|||||||
{
|
{
|
||||||
BLOCK "040904E4"
|
BLOCK "040904E4"
|
||||||
{
|
{
|
||||||
VALUE "FileVersion", "1.13.0.0"
|
VALUE "FileVersion", "1.14.0.0"
|
||||||
VALUE "LegalCopyright", "© 2010 - Rainy"
|
VALUE "LegalCopyright", "© 2010 - Rainy"
|
||||||
VALUE "ProductName", "Rainmeter"
|
VALUE "ProductName", "Rainmeter"
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
|
@ -29,6 +29,175 @@
|
|||||||
#include "../../Library/DisableThreadLibraryCalls.h" // contains DllMain entry point
|
#include "../../Library/DisableThreadLibraryCalls.h" // contains DllMain entry point
|
||||||
#include "../API/RainmeterAPI.h"
|
#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
|
struct MeasureData
|
||||||
{
|
{
|
||||||
std::wstring url;
|
std::wstring url;
|
||||||
@ -42,6 +211,7 @@ struct MeasureData
|
|||||||
std::wstring debugFileLocation;
|
std::wstring debugFileLocation;
|
||||||
LPCWSTR section;
|
LPCWSTR section;
|
||||||
void* skin;
|
void* skin;
|
||||||
|
ProxySetting proxy;
|
||||||
HANDLE threadHandle;
|
HANDLE threadHandle;
|
||||||
HANDLE dlThreadHandle;
|
HANDLE dlThreadHandle;
|
||||||
int codepage;
|
int codepage;
|
||||||
@ -71,18 +241,17 @@ struct MeasureData
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
BYTE* DownloadUrl(std::wstring& url, DWORD* dwSize, bool forceReload);
|
BYTE* DownloadUrl(HINTERNET handle, std::wstring& url, DWORD* dwSize, bool forceReload);
|
||||||
void ShowError(int lineNumber, WCHAR* errorMsg = NULL);
|
|
||||||
unsigned __stdcall NetworkThreadProc(void* pParam);
|
unsigned __stdcall NetworkThreadProc(void* pParam);
|
||||||
unsigned __stdcall NetworkDownloadThreadProc(void* pParam);
|
unsigned __stdcall NetworkDownloadThreadProc(void* pParam);
|
||||||
void ParseData(MeasureData* measure, LPCSTR parseData, DWORD dwSize);
|
void ParseData(MeasureData* measure, LPCSTR parseData, DWORD dwSize);
|
||||||
|
|
||||||
CRITICAL_SECTION g_CriticalSection;
|
CRITICAL_SECTION g_CriticalSection;
|
||||||
|
ProxyCachePool* g_ProxyCachePool = NULL;
|
||||||
UINT g_InstanceCount = 0;
|
UINT g_InstanceCount = 0;
|
||||||
|
|
||||||
static std::vector<MeasureData*> g_Measures;
|
static std::vector<MeasureData*> g_Measures;
|
||||||
static bool g_Debug = false;
|
static bool g_Debug = false;
|
||||||
static HINTERNET g_InternetHandle = NULL;
|
|
||||||
|
|
||||||
static std::unordered_map<std::wstring, WCHAR> g_CERs;
|
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)
|
PLUGIN_EXPORT void Initialize(void** data, void* rm)
|
||||||
{
|
{
|
||||||
MeasureData* measure = new MeasureData;
|
MeasureData* measure = new MeasureData;
|
||||||
@ -548,19 +755,11 @@ PLUGIN_EXPORT void Initialize(void** data, void* rm)
|
|||||||
InitializeCriticalSection(&g_CriticalSection);
|
InitializeCriticalSection(&g_CriticalSection);
|
||||||
FillCharacterEntityReferences();
|
FillCharacterEntityReferences();
|
||||||
|
|
||||||
LPCWSTR proxy = RmReadString(rm, L"ProxyServer", L"");
|
SetupGlobalProxySetting();
|
||||||
g_InternetHandle = InternetOpen(L"Rainmeter WebParser plugin",
|
|
||||||
*proxy ? INTERNET_OPEN_TYPE_PROXY : INTERNET_OPEN_TYPE_PRECONFIG,
|
|
||||||
*proxy ? proxy : NULL,
|
|
||||||
NULL,
|
|
||||||
0);
|
|
||||||
|
|
||||||
if (g_InternetHandle == NULL)
|
|
||||||
{
|
|
||||||
ShowError(__LINE__);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetupProxySetting(measure->proxy, rm); // No support for DynamicVariables
|
||||||
|
|
||||||
++g_InstanceCount;
|
++g_InstanceCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -699,7 +898,7 @@ unsigned __stdcall NetworkThreadProc(void* pParam)
|
|||||||
MeasureData* measure = (MeasureData*)pParam;
|
MeasureData* measure = (MeasureData*)pParam;
|
||||||
DWORD dwSize = 0;
|
DWORD dwSize = 0;
|
||||||
|
|
||||||
BYTE* data = DownloadUrl(measure->url, &dwSize, measure->forceReload);
|
BYTE* data = DownloadUrl(measure->proxy.handle, measure->url, &dwSize, measure->forceReload);
|
||||||
|
|
||||||
if (data)
|
if (data)
|
||||||
{
|
{
|
||||||
@ -1433,6 +1632,8 @@ PLUGIN_EXPORT void Finalize(void* data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClearProxySetting(measure->proxy);
|
||||||
|
|
||||||
delete measure;
|
delete measure;
|
||||||
std::vector<MeasureData*>::iterator iter = std::find(g_Measures.begin(), g_Measures.end(), measure);
|
std::vector<MeasureData*>::iterator iter = std::find(g_Measures.begin(), g_Measures.end(), measure);
|
||||||
g_Measures.erase(iter);
|
g_Measures.erase(iter);
|
||||||
@ -1441,11 +1642,7 @@ PLUGIN_EXPORT void Finalize(void* data)
|
|||||||
if (g_InstanceCount == 0)
|
if (g_InstanceCount == 0)
|
||||||
{
|
{
|
||||||
// Last one, close all handles
|
// Last one, close all handles
|
||||||
if (g_InternetHandle)
|
ClearGlobalProxySetting();
|
||||||
{
|
|
||||||
InternetCloseHandle(g_InternetHandle);
|
|
||||||
g_InternetHandle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_CERs.clear();
|
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.
|
Downloads the given url and returns the webpage as dynamically allocated string.
|
||||||
You need to delete the returned string after use!
|
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;
|
HINTERNET hUrlDump;
|
||||||
DWORD dwSize;
|
DWORD dwSize;
|
||||||
@ -1478,13 +1675,13 @@ BYTE* DownloadUrl(std::wstring& url, DWORD* dwDataSize, bool forceReload)
|
|||||||
flags = INTERNET_FLAG_RELOAD;
|
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 (hUrlDump == NULL)
|
||||||
{
|
{
|
||||||
if (_wcsnicmp(url.c_str(), L"file://", 7) == 0) // file scheme
|
if (_wcsnicmp(url.c_str(), L"file://", 7) == 0) // file scheme
|
||||||
{
|
{
|
||||||
std::string urlACP = ConvertWideToAscii(url.c_str());
|
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)
|
if (hUrlDump == NULL)
|
||||||
@ -1647,7 +1844,7 @@ void ShowError(int lineNumber, WCHAR* errorMsg)
|
|||||||
|
|
||||||
UINT GetPluginVersion()
|
UINT GetPluginVersion()
|
||||||
{
|
{
|
||||||
return 1013;
|
return 1014;
|
||||||
}
|
}
|
||||||
|
|
||||||
LPCTSTR GetPluginAuthor()
|
LPCTSTR GetPluginAuthor()
|
||||||
|
Loading…
Reference in New Issue
Block a user