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

📄 sbinetvalidator.cpp

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

 /****************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
 
 #include <wchar.h>
 #include <stdio.h>
 
 #include "SBinetValidator.h"     // For this class
 #include "SBinetLog.h"           // For logging definitions
 #include "HttpUtils.hpp"
 #include "SBinetUtils.hpp"
 #include "SBinetChannel.h"
 
 using namespace std;
 
 /*****************************************************************************
  *****************************************************************************
  * SBinetValidator Implementation
  *****************************************************************************
  *****************************************************************************
  */
 
 #if defined(_decunix_) || defined(_solaris_)
 
 // On solaris,
 // wsncasecmp is defined in widec.h but we don't have the right comp. flags to get the prototype.
 // I'm not sure about decunix though.
 //
 extern "C" wsncasecmp(const wchar_t *, const wchar_t *, size_t);
 #define wcsncasecmp(s1,s2,n) wsncasecmp(s1,s2,n)
 
 #if 0
 static int my_wcsncasecmp(const wchar_t *s1, const wchar_t *s2,
 			  register size_t n)
 {
   register unsigned int u1, u2;
 
   for (; n != 0; --n) {
     u1 = (unsigned int) *s1++;
     u2 = (unsigned int) *s2++;
     if (HttpUtils::toUpper(u1) != HttpUtils::toUpper(u2)) {
       return HttpUtils::toUpper(u1) - HttpUtils::toUpper(u2);
     }
     if (u1 == '\0') {
       return 0;
     }
   }
   return 0;
 }
 #endif
 #endif
 
 SBinetValidator::SBinetValidator(VXIlogInterface *log, VXIunsigned diagTagBase)
   : SWIutilLogger(MODULE_SBINET, log, diagTagBase), _freshnessLifetime((time_t) -1),
     _refTime((time_t) -1), _sizeBytes(0), _eTag(NULL), _mustRevalidateF(false),
     _url(NULL), _lastModified((time_t) -1)
 {}
 
 SBinetValidator::~SBinetValidator()
 {
   delete [] _eTag;
   delete [] _url;
 }
 
 VXIinetResult SBinetValidator::Create(const VXIchar *filename, VXIulong sizeBytes,
                                       time_t refTime)
 {
   _lastModified = refTime;
   _refTime = refTime;
   return Create(filename, sizeBytes, (time_t) -1, (VXIMap *) NULL);
 }
 
 VXIinetResult SBinetValidator::Create(const VXIchar *url,
                                       time_t requestTime,
                                       const VXIMap *streamInfo)
 {
   if (url == NULL || !*url || streamInfo == NULL)
   {
     return VXIinet_RESULT_INVALID_ARGUMENT;
   }
 
   VXIint32 sizeBytes = 0;
   SBinetUtils::getInteger(streamInfo, INET_INFO_SIZE_BYTES, sizeBytes);
 
   return Create(url, (VXIulong) sizeBytes, requestTime, streamInfo);
 }
 
 static time_t computeRefTime(time_t requestTime,
                              const VXIMap* streamInfo,
                              time_t& dateTime)
 {
   // The algorithm is based on the RFC section 13.2.3 but instead of computing
   // an initial age, it computes a reference time that can later be used to
   // retrieve the age.
 
   // The algo in the RFC to compute current-age is as follows.
 
   //  response_delay = response_time - request_time;
   //  corrected_initial_age = corrected_received_age + response_delay;
   //  resident_time = now - response_time;
   //  current_age   = corrected_initial_age + resident_time;
 
   // Which can be rewritten as follows:
 
   //  current_age = (corrected_received_age + response_delay) + (now - response_time)
   //              = (corrected_received_age + response_time - request_time) + (now - response_time)
   //              = corrected_received_age + now - request_time
   //              = now - (request_time - corrected_received_age)
   // This algorithm computes the ref. time to be equal to request_time - corrected_received_age.
 
   // Using this algorithm has two advantages:
   //
   // 1) More efficient: less computation required to compute the ref. time
   // than to compute the corrected initial age. When computing the current
   //
   // 2) Only requires to store the ref. time in the validator rather than the
   // response time and the corrected initial age.
 
   VXIint32 tmp;
   time_t responseTime = time(NULL);
   time_t computed_age = (time_t) 0;
 
   if (SBinetUtils::getInteger(streamInfo, L"Date", tmp))
   {
     dateTime = (time_t) tmp;
     computed_age = responseTime - dateTime;
     if (computed_age < (time_t) 0) computed_age = (time_t) 0;
   }
   else
   {
     dateTime = responseTime;
   }
 
   if (SBinetUtils::getInteger(streamInfo, L"Age", tmp))
   {
     time_t age = (time_t) tmp;
     if (age > computed_age) computed_age = age;
   }
   return requestTime - computed_age;
 }
 
 VXIinetResult SBinetValidator::Create(const VXIchar *url, VXIulong sizeBytes,
                                       time_t requestTime,
                                       const VXIMap *streamInfo)
 {
   if (url == NULL || !*url)
   {
     return VXIinet_RESULT_INVALID_ARGUMENT;
   }
 
   if (_url)
     delete [] _url;
   _url = ::wcscpy(new VXIchar[::wcslen(url) + 1], url);
 
   _sizeBytes = sizeBytes;
   _freshnessLifetime = (time_t) -1;
 
   const VXIchar *eTag = NULL;
 
   delete [] _eTag;
 
   //   // Sanity check
   //   if (_expiresTime >= 0 && _lastModifiedTime >= _expiresTime)
   //     _expiresTime = 0;
 
   //   time_t now = time(NULL);
   //   if (_lastModifiedTime > now)
   //     _lastModifiedTime = now;
 
   if (streamInfo != NULL)
   {
     time_t dateTime;
     _refTime = computeRefTime(requestTime, streamInfo, dateTime);
 
     VXIint32 lastModified = -1;
     SBinetUtils::getInteger(streamInfo, L"Last-Modified", lastModified);
     _lastModified = (time_t) lastModified;
 
     eTag = SBinetUtils::getString(streamInfo, L"ETag");
 
     // Inspect the headers for other relevant directives ('no-cache' etc.)
     _freshnessLifetime = checkPragma(streamInfo);
     if (_freshnessLifetime == (time_t) -1)
     {
       _freshnessLifetime = checkCacheControl(streamInfo);
     }
 
     if (_freshnessLifetime == (time_t) -1)
     {
       VXIint32 expiresTime = -1;
 
       if (SBinetUtils::getInteger(streamInfo, L"Expires", expiresTime))
       {
         _freshnessLifetime = ((time_t) expiresTime) - dateTime;
       }
       else if (_lastModified != (time_t) -1)
       {
         // Use the last modified time from the map to determine a freshness lifetime.
         _freshnessLifetime = (time_t) ((dateTime - _lastModified) *
                                        SBinetChannel::getFreshnessFraction());
         time_t maxLifetime = SBinetChannel::getFreshnessLifetime();
         if (_freshnessLifetime > maxLifetime)
           _freshnessLifetime = maxLifetime;
       }
       else
       {
         Error(302, L"%s%s", L"URL", url);
         _freshnessLifetime = SBinetChannel::getMaxLifetime();
       }
     }
     if (_freshnessLifetime < (time_t) 0)
       _freshnessLifetime = (time_t) 0;
   }
 
   if (eTag == NULL || !*eTag)
   {
     _eTag = NULL;
   }
   else
   {
     _eTag = ::wcscpy(new VXIchar[::wcslen(eTag) + 1], eTag);
   }
 
   Log(L"SBinetValidator::Create");
   return VXIinet_RESULT_SUCCESS;
 }
 
 
 VXIinetResult SBinetValidator::Create(const VXIValue *content)
 {
   if (VXIValueGetType(content) != VALUE_CONTENT)
   {
     Error(214, L"Type: %d", VXIValueGetType(content));
     return VXIinet_RESULT_INVALID_ARGUMENT;
   }
 
   // Get the content
   const VXIchar *contentType;
   const VXIbyte *contentData;
   VXIulong contentSizeBytes;
   if ( VXIContentValue((const VXIContent*) content,
                        &contentType, &contentData,
 		       &contentSizeBytes) != VXIvalue_RESULT_SUCCESS )
   {
     Error(215, NULL);
     return VXIinet_RESULT_INVALID_ARGUMENT;
 
   }
   else if ( ::wcscmp(contentType, VALIDATOR_MIME_TYPE) != 0 )
   {
     Error(216, L"mimeType: %s", contentType);
     return VXIinet_RESULT_INVALID_ARGUMENT;
   }
 
   return Create(contentData, contentSizeBytes);
 }
 
 
 VXIinetResult SBinetValidator::Create(const VXIbyte *data, VXIulong contentSizeBytes)
 {
   // Unpack the data
   const VXIbyte *ptr = data;
 
   ::memcpy(&_refTime, ptr, sizeof _refTime);
   ptr += sizeof _refTime;
 
   ::memcpy(&_freshnessLifetime, ptr, sizeof _freshnessLifetime);
   ptr += sizeof _freshnessLifetime;
 
   ::memcpy(&_lastModified, ptr, sizeof _lastModified);
   ptr += sizeof _lastModified;
 
   ::memcpy(&_mustRevalidateF, ptr, sizeof _mustRevalidateF);
   ptr += sizeof _mustRevalidateF;
 
   ::memcpy(&_sizeBytes, ptr, sizeof _sizeBytes);
   ptr += sizeof _sizeBytes;
 
   int len;
   ::memcpy(&len, ptr, sizeof len);
   ptr += sizeof len;
 
   delete [] _eTag;
   if (len > 0)
   {
     int size = len * sizeof(VXIchar);
     _eTag = new VXIchar[len + 1];
     ::memcpy(_eTag, ptr, size);
     ptr += size;
     _eTag[len] = L'\0';
   }
   else
     _eTag = NULL;
 
   ::memcpy(&len, ptr, sizeof len);
   ptr += sizeof len;
 
   delete [] _url;
   if (len > 0)
   {
     int size = len * sizeof(VXIchar);
     _url = new VXIchar[len + 1];
     ::memcpy(_url, ptr, size);
     ptr += size;
     _url[len] = L'\0';
   }
   else
     _url = NULL;

⌨️ 快捷键说明

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