⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sbinetchannel.cpp

📁 sloedgy open sip stack source code
💻 CPP
📖 第 1 页 / 共 3 页
字号:

 /****************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.
  *
  ***********************************************************************/
 
#include <vxibuildopts.h>
#if P_VXI

#ifndef _SB_USE_STD_NAMESPACE
 #define _SB_USE_STD_NAMESPACE
 #endif
 
 #define SBINET_EXPORTS
 #include "vxi/VXItypes.h"
 #include "vxi/VXIvalue.h"
 #include "vxi/VXIinet.h"
 #include "vxi/VXItrd.h"
 #include "vxi/VXIlog.h"
 
 #include <vxi/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 <vxi/SWIList.hpp>
 #include <vxi/SWIinputStream.hpp>
 #include <vxi/SWIoutputStream.hpp>
 #include <vxi/SWIdataOutputStream.hpp>
 #include <vxi/SWIipAddress.hpp>
 
 /*****************************************************************************
  *****************************************************************************
  * SBinetChannel Implementation
  *****************************************************************************
  *****************************************************************************
  */

#if defined(_MSC_VER)
#pragma warning(disable:4061)
#endif
 
 //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)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -