?? sbinetchannel.cpp
字號:
/****************License************************************************ * * Copyright 2000-2003. ScanSoft, Inc. * * Use of this software is subject to notices and obligations set forth * in the SpeechWorks Public License - Software Version 1.2 which is * included with this software. * * ScanSoft is a registered trademark of ScanSoft, Inc., and OpenSpeech, * SpeechWorks and the SpeechWorks logo are registered trademarks or * trademarks of SpeechWorks International, Inc. in the United States * and other countries. * ***********************************************************************/ #ifndef _SB_USE_STD_NAMESPACE #define _SB_USE_STD_NAMESPACE #endif #define SBINET_EXPORTS #include "VXItypes.h" #include "VXIvalue.h" #include "VXIinet.h" #include "VXItrd.h" #include "VXIlog.h" #include <SBinet.h> #include "SBinetLog.h" #include "SBinetHttpCacheStream.hpp" #include "SBinetTimedStream.hpp" #include "SBinetFileStream.hpp" #include "SBinetChannel.h" #include "SBinetURL.h" #include "SBinetCookie.h" #include "SBinetProxyMatcher.hpp" #include "SBinetUtils.hpp" #include "SBinetHttpConnection.hpp" #include "SBinetSSLsocket.hpp" #include <SWIList.hpp> #include <SWIinputStream.hpp> #include <SWIoutputStream.hpp> #include <SWIdataOutputStream.hpp> #include <SWIipAddress.hpp> /***************************************************************************** ***************************************************************************** * SBinetChannel Implementation ***************************************************************************** ***************************************************************************** */ //Static data members VXItrdMutex *SBinetChannel::_extensionRulesMutex = NULL; VXIMap *SBinetChannel::_extensionRules = NULL; SBinetNString *SBinetChannel::_userAgent = NULL; double SBinetChannel::_freshnessFraction = SBINET_FRESHNESS_FRACTION_DEFAULT; time_t SBinetChannel::_freshnessLifetime = (time_t) SBINET_FRESHNESS_LIFETIME_DEFAULT; time_t SBinetChannel::_maxLifetime = (time_t) SBINET_MAX_LIFETIME_DEFAULT; VXIint32 SBinetChannel::_pageLoadTimeout = SBINET_PAGE_LOADING_TIMEOUT_DEFAULT; VXIint32 SBinetChannel::_postContinueTimeout = SBINET_POST_CONTINUE_TIMEOUT_DEFAULT; SWIList SBinetChannel::_proxyMatcherList; bool SBinetChannel::_usePersistentConnections = true; SBinetString *SBinetChannel::_defaultMimeType = NULL; SBinetChannel::SBinetChannel( VXIlogInterface* pVXILog, VXIunsigned diagLogBase, VXIcacheInterface *pVXIcache): SWIutilLogger(MODULE_SBINET, pVXILog, diagLogBase), _cookieList(), _jarChanged(true), _cookiesEnabled(false), _connectionCount(0), _pVXILog(pVXILog), _pVXICache(pVXIcache), _echoStream(NULL) { Diag (MODULE_SBINET_CHANNEL_TAGID, L"SBinetChannel::SBinetChannel", L"0x%p", pVXILog); // Init interface VXIinetInterface::GetVersion = SBinetChannel::GetVersion; VXIinetInterface::GetImplementationName = SBinetChannel::GetImplementationName; VXIinetInterface::Prefetch = staticPrefetch; VXIinetInterface::Open = staticOpen; VXIinetInterface::Read = staticRead; VXIinetInterface::Write = staticWrite; VXIinetInterface::Close = staticClose; VXIinetInterface::SetCookieJar = staticSetCookieJar; VXIinetInterface::GetCookieJar = staticGetCookieJar; if ((DiagIsEnabled(MODULE_SBINET_DUMP_HTTP_MSGS)) && (LOG_CONTENT_METHODS_SUPPORTED(_pVXILog))) { VXIString *logKey = NULL, *logValue = NULL; if (_pVXILog->ContentOpen(_pVXILog, MODULE_SBINET, VXI_MIME_TEXT, &logKey, &logValue, &_echoStream) == VXIlog_RESULT_SUCCESS) { Diag(MODULE_SBINET_DUMP_HTTP_MSGS, NULL, L"Dumping HTTP messages, %s=%s", VXIStringCStr(logKey), VXIStringCStr(logValue)); VXIStringDestroy(&logKey); VXIStringDestroy(&logValue); } } } SBinetChannel::~SBinetChannel( ) { Diag (MODULE_SBINET_CHANNEL_TAGID, L"SBinetChannel::~SBinetChannel", NULL); closeHttpConnections(); closeAllStreams(); deleteAllCookies(); if (_echoStream) { _pVXILog->ContentClose(_pVXILog, &_echoStream); } // NOP // // NOP // // NOP // } /* * Prefetch: For now punt, eventually spawn thread to call Open() into /dev/null */ VXIinetResult SBinetChannel::prefetch(const VXIchar* pszModuleName, const VXIchar* pszName, VXIinetOpenMode eMode, VXIint32 nFlags, const VXIMap* pProperties ) { #if 0 // NOT YET IMPLEMENTED /* * Add prefetch request to prefetch queue. These requests are * processed when the fetch engine is idle, and the fetched * documents are stored in the Inet cache until retrieved by * a subsequent Open call. Note that in order for prefetching * to work, caching must be enabled, the fetched document must * be cachable (server must not return a 'no-cache' directive) * and the caching mode must not be SAFE. */ Diag( MODULE_SBINET_CHANNEL_TAGID, L"SBinetChannel::Prefetch", L"(%s)", pszName ); #endif return VXIinet_RESULT_SUCCESS; } VXIinetResult SBinetChannel::closeAllStreams() { // should interate over open stream and close gracefully return(VXIinet_RESULT_SUCCESS); } static VXIinetResult parseURL(const VXIchar *pszName, const VXIMap *properties, SWIutilLogger *logger, SBinetURL *& url) { const VXIchar *pszUrlBase = SBinetUtils::getString(properties, INET_URL_BASE); VXIinetResult rc = SBinetURL::create(pszName,pszUrlBase,url); if (rc == VXIinet_RESULT_OUT_OF_MEMORY) { logger->Error(103, NULL); } else if (rc != VXIinet_RESULT_SUCCESS) { logger->Error(200, L"%s%s%s%s", L"Operation", L"Open", L"URL", (pszName != NULL) ? pszName : L"NULL"); } return rc; } VXIinetStream* SBinetChannel::createHttpStream(SBinetURL *url, const VXIMap *properties) { SBinetHttpStream::SubmitMethod method = SBinetHttpStream::GET_METHOD; const VXIchar *methodStr = SBinetUtils::getString(properties, INET_SUBMIT_METHOD); if (methodStr == NULL) methodStr = INET_SUBMIT_METHOD_DEFAULT; if (!::wcscmp(methodStr, INET_SUBMIT_METHOD_POST)) method = SBinetHttpStream::POST_METHOD; SBinetStoppableStream *stream = NULL; if (method == SBinetHttpStream::GET_METHOD) { // Get method, append the query arguments to the URL and create a cache // stream. const VXIMap *queryArgs = (const VXIMap *)VXIMapGetProperty(properties, INET_URL_QUERY_ARGS); url->appendQueryArgsToURL(queryArgs); stream = new SBinetHttpCacheStream(url, method, this, getCache(), GetLog(), GetDiagBase()); } else { // No caching for POST operations. stream = new SBinetHttpStream(url, method, this, GetLog(), GetDiagBase()); } if (stream != NULL) return new SBinetTimedStream(stream, GetLog(), GetDiagBase()); else return NULL; } VXIinetResult SBinetChannel::createStream(SBinetURL *url, const VXIMap *properties, VXIinetStream* &stream) { /* * Note: Stream now owns url and must delete on cleanup */ switch (url->getProtocol()) { case SBinetURL::HTTP_PROTOCOL: case SBinetURL::HTTPS_PROTOCOL: stream = createHttpStream(url, properties); break; case SBinetURL::FILE_PROTOCOL: stream = new SBinetFileStream(url, this, GetLog(), GetDiagBase()); break; default: // Can't really happen. stream = NULL; break; } if (!stream) { Error(103, NULL); delete url; return VXIinet_RESULT_OUT_OF_MEMORY; } return VXIinet_RESULT_SUCCESS; } /* * Open: Serious work here. * Parse URL and combine with base * Collect properties and query args * Call appropriate Stream constructor base on URL scheme (http or file) * Call Open() on stream */ VXIinetResult SBinetChannel::open(const VXIchar* pszModuleName, const VXIchar* pszName, VXIinetOpenMode eMode, VXIint32 nFlags, const VXIMap* pProperties, VXIMap* pmapStreamInfo, VXIinetStream** ppStream) { if (eMode != INET_MODE_READ) return(VXIinet_RESULT_UNSUPPORTED); if(!ppStream) { Error(200, L"%s%s%s%s", L"Operation", L"Open", L"URL", (pszName != NULL) ? pszName : L"NULL"); return(VXIinet_RESULT_INVALID_ARGUMENT); } Diag (MODULE_SBINET_CHANNEL_TAGID, L"SBinetChannel::Open", L"(%s)", pszName != NULL ? pszName : L"NULL"); SBinetURL *url; VXIinetResult rc = ::parseURL(pszName, pProperties, this, url); if (rc != VXIinet_RESULT_SUCCESS) return rc; rc = createStream(url, pProperties, *ppStream); if (rc != VXIinet_RESULT_SUCCESS) return rc; rc = (*ppStream)->Open(nFlags, pProperties, pmapStreamInfo); switch (rc) { case VXIinet_RESULT_SUCCESS: return VXIinet_RESULT_SUCCESS; break; case VXIinet_RESULT_NOT_MODIFIED: case VXIinet_RESULT_LOCAL_FILE: // no logging to perform. break; case VXIinet_RESULT_FETCH_TIMEOUT: Error(228, L"%s%s", L"URL", url->getAbsolute()); // no break: intentional default: Error(204, L"%s%s%s%d", L"URL", url->getAbsolute(), L"rc",rc); break; } delete (*ppStream); *ppStream = NULL; return rc; } VXIinetResult SBinetChannel::close(VXIinetStream** ppStream) { if (ppStream == NULL) { Error(200, L"%s%s", L"Operation", L"Close"); return(VXIinet_RESULT_INVALID_ARGUMENT); } VXIinetStream* st = *ppStream; VXIinetResult err; if(st != NULL) { err = st->Close(); delete st; st = NULL; } else { Error(200, L"%s%s", L"Operation", L"Close"); err = VXIinet_RESULT_INVALID_ARGUMENT; } *ppStream = NULL; return(err); } VXIinetResult SBinetChannel::setCookieJar( const VXIVector* pJar ) { deleteAllCookies(); if (pJar == NULL) { // NULL jar means 'disable cookie usage' _jarChanged = false; _cookiesEnabled = false; return VXIinet_RESULT_SUCCESS; } _cookiesEnabled = true; // Enable cookie usage VXIunsigned numElements = VXIVectorLength(pJar); for (VXIunsigned i = 0; i < numElements; i++) { const VXIMap *cookie_map = (const VXIMap *) VXIVectorGetElement(pJar, i); if (cookie_map == NULL) { Error (212, NULL); continue; } if (VXIValueGetType((const VXIValue *) cookie_map) != VALUE_MAP) { Error (213, L"%s%d", L"VXIValueType", VXIValueGetType((const VXIValue *) cookie_map)); continue; } VXIint32 tempInt = 0; SBinetUtils::getInteger(cookie_map, INET_COOKIE_EXPIRES, tempInt); time_t expires = (time_t) tempInt; // Check if the cookie is expired, if so don't add it, zero // expiration time means the cookie is not persistent and should not be added. if(expires < time(0)) continue; // Get the name const VXIchar *tempStr = SBinetUtils::getString(cookie_map, INET_COOKIE_NAME); if (tempStr == NULL) { Error(106, NULL); continue; } // convert to narrow string. SBinetNString name = tempStr; // Get the domain tempStr = SBinetUtils::getString(cookie_map, INET_COOKIE_DOMAIN); SBinetNString domain; if(tempStr != NULL) { domain = tempStr; } // Get the path tempStr = SBinetUtils::getString(cookie_map, INET_COOKIE_PATH); SBinetNString path; if(tempStr != NULL) { path = tempStr; } // Get the secure flag bool secure = SBinetUtils::getInteger(cookie_map, INET_COOKIE_SECURE, tempInt) && tempInt; // AC: Why would it be an error to have a cookie withouth the secure attribute? // if(tempInt == NULL) // { // Error(200, NULL); // continue; // } // Get the value tempStr = SBinetUtils::getString(cookie_map,INET_COOKIE_VALUE); SBinetNString value; if(tempStr != NULL) { value = tempStr; } // Create the cookie SBinetCookie* pSBinetCookie = new SBinetCookie(domain.c_str(), path.c_str(), name.c_str(), value.c_str(), expires, secure); // Add the cookie to the channel's list if (pSBinetCookie && !addCookie(pSBinetCookie)) delete pSBinetCookie; // Could not add } _jarChanged = false; return VXIinet_RESULT_SUCCESS; } VXIinetResult SBinetChannel::getCookieJar( VXIVector** ppJar, VXIbool* ppfChanged ) { time_t now = time(NULL); if (ppJar == NULL) { Error(200, L"%s%s", L"Operation", L"GetCookieJar"); return VXIinet_RESULT_INVALID_ARGUMENT; } *ppJar = VXIVectorCreate(); if(*ppJar == NULL) { Error(103, NULL); return VXIinet_RESULT_OUT_OF_MEMORY; } // Parse the channel's cookie list SWIList::Iterator iter(_cookieList); while (iter.hasNext()) { SBinetCookie *cookie = (SBinetCookie *) iter.next(); if (cookie->getExpires() < now) continue; VXIMap *cookie_map = VXIMapCreate(); if(cookie_map == NULL) { VXIVectorDestroy(ppJar); Error(103, NULL); return VXIinet_RESULT_OUT_OF_MEMORY;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -