📄 sbinet.cpp
字号:
SBinetTerminate::~SBinetTerminate(){ if (g_SBinet) { // To avoid having anything reference the global during termination SBinet *temp = g_SBinet; g_SBinet = NULL; // Disable logging during termination, the log resource is // probably gone by now so trying to use it as will be done at // shutdown causes a crash temp->Terminate(TRUE); delete temp; }}/**************************************************************************** **************************************************************************** * SBinet methods: Initializations * **************************************************************************** **************************************************************************** */SBinet::SBinet(VXIlogInterface *log, VXIunsigned diagLogBase) : SBinetLogger(MODULE_SBINET, log, diagLogBase), m_pEventThread(0), m_pLibwwwMutex(0), m_pEventTimer(0), m_nSleepInterval(0), m_nInitializeStatus(NULL), m_fDone(false), m_fShutdown(false), m_strCacheFolder(), m_nCacheEntryMaxSizeMB(0), m_nCacheEntryExpTimeSec(0), m_fInitializedCache(false), m_strProxyServer(), m_nProxyPort(0), m_extensionRules(0), runEventLoop(0){}SBinet::~SBinet(){}//// Initialize SBinet//VXIinetResult SBinet::Init(const VXIchar* pszCacheFolder, const VXIint nCacheTotalSizeMB, const VXIint nCacheEntryMaxSizeMB, const VXIint nCacheEntryExpTimeSec, const VXIchar* pszProxyServer, const VXIulong nProxyPort, const VXIchar* userAgentName, const VXIMap* extensionRules){ // Check if the environment is correct for supporting SBinet VXIinetResult rc = CheckEnvironment(); if (rc != VXIinet_RESULT_SUCCESS) return rc; m_pEventThread = NULL; m_pEventTimer = NULL; m_nSleepInterval = 5 * 1000L; // 5 second sleep interval m_fDone = false; m_fShutdown = false; m_strCacheFolder = ( pszCacheFolder != NULL ) ? pszCacheFolder : L""; m_nCacheTotalSizeMB = nCacheTotalSizeMB; m_nCacheEntryMaxSizeMB = nCacheEntryMaxSizeMB; m_nCacheEntryExpTimeSec = nCacheEntryExpTimeSec; m_fInitializedCache = false; if (pszProxyServer != NULL ) m_strProxyServer = pszProxyServer; m_nProxyPort = nProxyPort; // Have to parse the user agent name#ifdef OPENVXI const VXIchar *tempAgent = OSBINET_USER_AGENT_NAME_DEFAULT;#else const VXIchar *tempAgent = SBINET_USER_AGENT_NAME_DEFAULT;#endif if (( userAgentName ) && ( userAgentName[0] )) tempAgent = userAgentName; const VXIchar *ptr = tempAgent; while (iswspace(*ptr)) ptr++; while ((*ptr) && (*ptr != L'/')) { m_strUserAgentApp += (char) *ptr; ptr++; } if (*ptr) ptr++; while (iswspace(*ptr)) ptr++; while ((iswalnum(*ptr)) || (*ptr == L'.')) { m_strUserAgentVersion += (char) *ptr; ptr++; } if ((m_strUserAgentApp.length() == 0) || (m_strUserAgentVersion.length() == 0)) { Error(100,NULL); return VXIinet_RESULT_INVALID_ARGUMENT; } VXItrdResult eTrdResult = VXItrdTimerCreate( &m_pEventTimer ); if (eTrdResult != VXItrd_RESULT_SUCCESS) { Error(100,NULL); return VXIinet_RESULT_SYSTEM_ERROR; } eTrdResult = VXItrdMutexCreate( &m_pLibwwwMutex ); if (eTrdResult != VXItrd_RESULT_SUCCESS) { Error(100,NULL); return VXIinet_RESULT_SYSTEM_ERROR; } // Initialize the cache lock table SBinetCacheLockTable::Init(GetLog(), GetDiagBase()); // Create timer. The EventThreadMain wakes this timer when it is complete. eTrdResult = VXItrdTimerCreate(&m_nInitializeStatus); if (eTrdResult != VXItrd_RESULT_SUCCESS) { Error(100,NULL); return VXIinet_RESULT_SYSTEM_ERROR; } runEventLoop = 1; eTrdResult = VXItrdThreadCreate(&m_pEventThread, SBinet::EventThreadMain, this); if (eTrdResult != VXItrd_RESULT_SUCCESS) { Error(100,NULL); return VXIinet_RESULT_SYSTEM_ERROR; } if (extensionRules) { m_extensionRules = VXIMapClone(extensionRules); } else m_extensionRules = NULL; // Spin while event thread inits libwww VXIbool done = FALSE; while (!done) VXItrdTimerSleep(m_nInitializeStatus, 10000, &done); VXItrdTimerDestroy(&m_nInitializeStatus); return rc;}//// Terminate SBinet//VXIinetResult SBinet::Terminate(VXIbool clearLogResource){ VXIinetResult rc = VXIinet_RESULT_SUCCESS; if (clearLogResource ) SetLog(NULL, GetDiagBase()); TerminateCache(); // Shut down the cache lock table SBinetCacheLockTable::ShutDown(GetLog()); // Shut down the cookies module HTCookie_deleteCallbacks(); // HTCookie_terminate(); // Terminate cookies module! HT BUG, HTLIST CRASHES (MEMORY ACCESS VIOLATION) if (m_pEventThread) { m_fShutdown = true; VXItrdThreadArg nExitResult; runEventLoop = 0; SBinetHTEventList_stopLoop (); // Wait for event thread to exit VXItrdResult eTrdResult = VXItrdThreadJoin(m_pEventThread, &nExitResult, 3 * 1000); /* if (eTrdResult == VXItrd_RESULT_SUCCESS) return (rc = VXIinet_RESULT_SUCCESS); else return (rc = VXIinet_RESULT_SYSTEM_ERROR); */ VXItrdThreadDestroyHandle( &m_pEventThread ); } if (m_pEventTimer ) VXItrdTimerDestroy( &m_pEventTimer ); if (m_pLibwwwMutex ) VXItrdMutexDestroy( &m_pLibwwwMutex ); if (m_extensionRules) { VXIMapDestroy(&(m_extensionRules)); m_extensionRules = NULL; } // TODO: Scan Instance and Stream maps and delete outstanding objects return rc;}//// Check if the environment properly supports SBinet//VXIinetResult SBinet::CheckEnvironment(){ VXIinetResult rc = VXIinet_RESULT_SUCCESS;#ifdef WIN32 // Get the Microsoft Internet Explorer version, must have version // 5.0 or later otherwise InternetCrackUrl() rejects various // file:// URL formats that we need to support. Base this off the // version of the DLL that implements the browser as documented at // http://support.microsoft.com/support/kb/articles/q164/5/39.asp, // the IE 5 GA release = 5.00.2014.213 static const wchar_t IE_DLL_NAME[] = L"shdocvw.dll"; static const int IE_DLL_VER_1 = 5; static const int IE_DLL_VER_2 = 0; static const int IE_DLL_VER_3 = 2014; static const int IE_DLL_VER_4 = 213; VXIint infoSize = GetFileVersionInfoSize((wchar_t *) IE_DLL_NAME, 0); if (infoSize <= 0) { // Could not find the DLL or version info not available Error(105, NULL); rc = VXIinet_RESULT_PLATFORM_ERROR; } else { VXIbyte *infoData = new VXIbyte [infoSize]; if (infoData == NULL) { Error(103, NULL); rc = VXIinet_RESULT_OUT_OF_MEMORY; } else { LPDWORD dwResource; UINT cnSize; if ((GetFileVersionInfo((wchar_t*)IE_DLL_NAME, 0,infoSize,infoData)==0)|| (VerQueryValue(infoData, L"\\", (LPVOID*)(&dwResource), &cnSize)==0)){ // Version info not available Error(105, NULL); rc = VXIinet_RESULT_PLATFORM_ERROR; } else { Diag(MODULE_SBINET_BASE_TAGID, NULL, L"Microsoft Internet Explorer %2d.%02d.%04d.%d is active", HIWORD(dwResource[2]), LOWORD(dwResource[2]), HIWORD(dwResource[3]), LOWORD(dwResource[3])); // Check if the DLL's version is OK for us bool badVersion = false; if (HIWORD(dwResource[2]) < IE_DLL_VER_1) badVersion = true; else if (HIWORD(dwResource[2]) == IE_DLL_VER_1) { if (LOWORD(dwResource[2]) < IE_DLL_VER_2) badVersion = true; else if (LOWORD(dwResource[2]) == IE_DLL_VER_2) { if (HIWORD(dwResource[3]) < IE_DLL_VER_3) badVersion = true; else if (HIWORD(dwResource[3]) == IE_DLL_VER_3) { if (LOWORD(dwResource[3]) < IE_DLL_VER_4) badVersion = true; } } } if (badVersion) { Error(104, L"%s%d%s%d%s%d%s%d", L"IEMajor", HIWORD(dwResource[2]), L"IEMinor", LOWORD(dwResource[2]), L"IEBuild", HIWORD(dwResource[3]), L"IEPatch", LOWORD(dwResource[3])); rc = VXIinet_RESULT_PLATFORM_ERROR; } } delete [] infoData; } }#endif return rc;}// Confirmation callback - used for the lock removalBOOL SBinet::CacheLockRemovalConfirmCallback(HTRequest *request, HTAlertOpcode op, int msgnum, const char *deflt, void *input, HTAlertPar *reply){ // callback because there is a lock file - asking if it can be // removed. Answer is YES if (msgnum == HT_MSG_CACHE_LOCK) { return TRUE; } return FALSE;}//// InitializeCache:// VXIinetResult SBinet::InitializeCache(){ VXIinetResult retCode; const VXIchar* pszCacheFolder = m_strCacheFolder.c_str(); // If no cache folder was specified, or cache // parameters are invalid then don't use the cache if (( pszCacheFolder == NULL ) || ( pszCacheFolder[0] == L'\0' ) || ( m_nCacheTotalSizeMB == 0 ) || ( m_nCacheEntryMaxSizeMB == 0 ) || ( m_nCacheEntryExpTimeSec == 0 )) { Error(303, NULL); return (VXIinet_RESULT_SUCCESS); // !! } VXIint len = ::wcslen( pszCacheFolder ) + 1; char *tempStr; // Simplify path, get rid of double or trailing path separators, etc.#ifdef WIN32 VXIchar *ignored; VXIchar *wTempStr; // Find out the required buffer size len = GetFullPathName( pszCacheFolder, 0, NULL, &ignored ); if (len == 0) { Error(202,NULL); return VXIinet_RESULT_INVALID_ARGUMENT; } wTempStr = new VXIchar [len + 1]; // Now process the path if (GetFullPathName( pszCacheFolder, len, wTempStr, &ignored ) == 0) { Error(202,NULL); return VXIinet_RESULT_INVALID_ARGUMENT; } tempStr = new char [len + 1]; ::wcstombs( tempStr, wTempStr, len + 1 ); delete [] wTempStr;#else tempStr = new char [len]; ::wcstombs( tempStr, pszCacheFolder, len ); HTSimplify( &tempStr );#endif char *pTempStr; if (::strstr( tempStr, "file:/" ) == tempStr ) pTempStr = tempStr + ::strlen( "file:/" ); else if (::strstr( tempStr, "file:" ) == tempStr ) pTempStr = tempStr + ::strlen( "file:" ); else pTempStr = tempStr; char *parsedTempStr = HTLocalToWWW( pTempStr, "" ); // Register the confirmation callback if (HTAlert_add(CacheLockRemovalConfirmCallback, HT_A_CONFIRM) == 0) { Error(202,NULL); return VXIinet_RESULT_IO_ERROR; } if (HTCacheInit( parsedTempStr, m_nCacheTotalSizeMB ) == NO ) { Error(202,NULL); retCode = VXIinet_RESULT_IO_ERROR; } else { HTCacheMode_setMaxCacheEntrySize( m_nCacheEntryMaxSizeMB ); HTCacheMode_setDefaultExpiration( m_nCacheEntryExpTimeSec ); // At last, enable or disable the persistent cache HTCacheMode_setEnabled(1); Diag (MODULE_SBINET_TAGID, L"SBinet::InitializeCache", L"Enabled Inet cache, folder is %S", parsedTempStr); // TODO // typedef enum _HTExpiresMode {HT_EXPIRES_IGNORE=0, HT_EXPIRES_NOTIFY, HT_EXPIRES_AUTO} HTExpiresMode; // extern void HTCacheMode_setExpires (HTExpiresMode mode); m_fInitializedCache = true; retCode = VXIinet_RESULT_SUCCESS; } // Cleanup if (tempStr != parsedTempStr ) delete [] tempStr; HT_FREE( parsedTempStr ); return ( retCode );}VXIinetResult SBinet::TerminateCache( void ){ if (m_fInitializedCache ) { HTCacheTerminate(); m_fInitializedCache = false; } return VXIinet_RESULT_SUCCESS;}VXIinetResult SBinet::InitializeProxy (void ){ const VXIulong nProxyPort = m_nProxyPort; VXIint len = m_strProxyServer.length(); if (len < 1 ) return ( VXIinet_RESULT_SUCCESS ); // No proxy specified len++; char *proxyID = new char [ len + 32 ]; ::strcpy( proxyID, "http://" ); VXIint httpLen = ::strlen( "http://" ); ::wcstombs( proxyID + httpLen, m_strProxyServer.c_str(), len ); sprintf( proxyID + httpLen + len - 1, ":%d", nProxyPort ); // Register the proxy for http, https and ftp requests VXIinetResult eResult = (HTProxy_add( "http", proxyID ) ? VXIinet_RESULT_SUCCESS : VXIinet_RESULT_FATAL_ERROR); if (eResult == VXIinet_RESULT_SUCCESS ) eResult = (HTProxy_add( "https", proxyID ) ? VXIinet_RESULT_SUCCESS : VXIinet_RESULT_FATAL_ERROR); if (eResult == VXIinet_RESULT_SUCCESS ) eResult = (HTProxy_add( "ftp", proxyID ) ? VXIinet_RESULT_SUCCESS : VXIinet_RESULT_FATAL_ERROR); delete [] proxyID; return (eResult );}/**************************************************************************** **************************************************************************** * SBinetInterface Implementation: Just call corresponding routine on channel * **************************************************************************** **************************************************************************** */SBinetInterface::SBinetInterface( VXIlogInterface* pVXILog, VXIunsigned diagLogBase ) : SBinetLogger (MODULE_SBINET_INTERFACE, pVXILog, diagLogBase) { m_ch = new SBinetChannel(pVXILog, diagLogBase); // Init interface VXIinetInterface::GetVersion = SBinetInterface::GetVersion; VXIinetInterface::GetImplementationName = SBinetInterface::GetImplementationName; VXIinetInterface::Prefetch = Prefetch; VXIinetInterface::Open = Open; VXIinetInterface::Read = Read; VXIinetInterface::Write = Write; VXIinetInterface::Close = Close; VXIinetInterface::SetCookieJar = SetCookieJar; VXIinetInterface::GetCookieJar = GetCookieJar;}SBinetInterface::~SBinetInterface() { if (m_ch) { m_ch->CloseAll(); delete m_ch; m_ch = NULL; } }voidSBinetInterface::LockLibwww(){ g_SBinet->LockLibwww();}voidSBinetInterface::UnlockLibwww(){ g_SBinet->UnlockLibwww();}const VXIString*SBinetInterface::mapExtension(const VXIchar* ext ) { return (g_SBinet->mapExtension(ext));}/* * Call Channel method */VXIint32 SBinetInterface::GetVersion(void){ return VXI_CURRENT_VERSION;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -