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

📄 sbinetcookie.cpp

📁 sloedgy open sip stack source code
💻 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.
  *
  ***********************************************************************/
 
#include <vxibuildopts.h>
#if P_VXI

 #ifndef _SB_USE_STD_NAMESPACE
 #define _SB_USE_STD_NAMESPACE
 #endif
 
 #include "SBinetCookie.h"
 #include "SBinetURL.h"
 #include "HttpUtils.hpp"
 #include "util_date.h"
 #include "ap_ctype.h"
 #include "SWIutilLogger.hpp"
 #include "SBinetLog.h"
 #include "SBinetUtils.hpp"
 
 /*****************************************************************************
  *****************************************************************************
  * SBinetCookie Implementation
  *****************************************************************************
  *****************************************************************************
  */
 
 bool SBinetCookie::matchExact(const SBinetCookie *cookie) const
 {
   if (strcasecmp(_Name.c_str(), cookie->_Name.c_str())) return(false);
   if (strcasecmp(_Domain.c_str(), cookie->_Domain.c_str())) return(false);
   if (strcasecmp(_Path.c_str(), cookie->_Path.c_str())) return(false);
 
   return(true);
 }
 
 bool SBinetCookie::matchDomain(const char *cdomain,
                                const char *domain,
                                const SWIutilLogger *logger)
 {
 
   bool match = true;
 
   // Domain name must belong to the domain for the cookie.  The rule is that
   // the cookie's domain must be a suffix of domain.
   int cDomLen = cdomain == NULL ? 0 : strlen(cdomain);
   int domlen = domain == NULL ? 0 : strlen(domain);
 
   if (cDomLen > domlen)
     match = false;
   else if (cDomLen > 0 &&
            strcasecmp(domain + (domlen - cDomLen), cdomain) != 0)
     match = false;
 
   if (logger && logger->DiagIsEnabled(MODULE_SBINET_COOKIE_TAGID))
   {
     logger->Diag(MODULE_SBINET_COOKIE_TAGID,
                  L"SBinetCookie::matchDomain",
                  L"cdomain: '%S', domain: '%S', match = '%s'",
                  cdomain, domain, match ? L"true" : L"false");
   }
   return match;
 }
 
 bool SBinetCookie::matchPath(const char *cpath,
                              const char *path,
                              const SWIutilLogger *logger)
 {
   bool match = true;
 
   // If the cookie path does not start with a /, then there is no possible
   // match.
   if (!cpath || *cpath != '/')
     match = false;
 
   // Idem for the path.
   else if (!path || *path != '/')
     match = false;
 
   else
   {
     const char *p = path + 1;
     const char *cp = cpath + 1;
 
     // First determine where the first difference is.
     while (*p && *cp &&
            SBinetHttpUtils::toLower(*p) == SBinetHttpUtils::toLower(*cp))
     {
       p++;
       cp++;
     }
 
     switch (*cp)
     {
      case '\0':
        // The first mismatch is at the end of the cookie-path, if the previous
        // character is a slash, this a match.  Otherwise, we have to make sure
        // that the mismatch char on the path is an anchor, a slash or a query
        // arg delimiter.
        if (*(cp - 1) != '/' && *p && *p != '/' && *p != '?' && *p != '#')
          match = false;
        break;
      case '/':
        // The first mismatch is / on the cookie-path.  If we did not get till
        // the end of the path, the cookie-path is not a prefix of the path.
        // However, if the mismatch character on the path is an anchor or a
        // query argument delimiter, then cookie-path is a prefix of path.
        if (*p && *p != '?' && *p != '#')
          match = false;
        break;
      default:
        match = false;
        break;
     }
   }
 
   if (logger && logger->DiagIsEnabled(MODULE_SBINET_COOKIE_TAGID))
   {
     logger->Diag(MODULE_SBINET_COOKIE_TAGID, L"SBinetCookie::matchPath",
                  L"cpath: '%S', path: '%S', match = '%s'",
                  cpath, path, match ? L"true" : L"false");
   }
   return match;
 }
 
 
 bool SBinetCookie::matchRequest(const char *domain,
                                 const char *path,
                                 const SWIutilLogger* logger) const
 {
   bool match = true;
 
   if (!matchDomain(_Domain.c_str(), domain, logger))
   {
     match = false;
   }
   else if (!matchPath(_Path.c_str(), path, logger))
   {
     match = false;
   }
 
   // TBD, if port was specified by the remote web server for the
   // cookie, the port must be included in the list of ports of the
   // cookie's port attribute. We aren't returning that information yet
   // so we don't even have a port stored in our cookies.
 
   if (logger && logger->DiagIsEnabled(MODULE_SBINET_COOKIE_TAGID))
   {
     char expStr[64];
     logger->Diag(MODULE_SBINET_COOKIE_TAGID, L"SBinetCookie::matchRequest",
 		 L"match: %s, (domain = '%S', path = '%S') compared to "
 		 L"(name = '%S', value = '%S', domain = '%S', "
 		 L"path = '%S', expires = %S (%d), secure = %s)",
 		 (match ? L"true" : L"false"), domain, path, _Name.c_str(),
 		 _Value.c_str(), _Domain.c_str(), _Path.c_str(),
 		 SBinetUtils::getTimeStampStr(_nExpires, expStr),
 		 _nExpires, (_fSecure ? L"true" : L"false"));
   }
 
   return match;
 }
 
 SBinetCookie* SBinetCookie::parse(const SBinetURL *url,
                                   const char *&cookiespec,
                                   const SWIutilLogger *logger)
 {
   const char *p = cookiespec;
 
   for (;;)
   {
     while (*p && ap_isspace(*p)) p++;
 
     if (!*p)
     {
       cookiespec = p;
       return NULL;
     }
 
     if (*p == ',')
     {
       // empty header.
       p++;
     }
     else
       break;
   }
 
   SBinetCookie *cookie = new SBinetCookie();
 
   cookiespec = p;
   p = SBinetHttpUtils::getToken(p, cookie->_Name);
 
   if (p == NULL)
   {
     if (logger) logger->Error(252, L"%s%S", L"cookiespec", cookiespec);
     goto failure;
   }
 
   if ((p = SBinetHttpUtils::expectChar(p,"=")) == NULL || !*p)
   {
     if (logger) logger->Error(253, L"%s%S", L"cookiespec", cookiespec);
     goto failure;
   }
 
   p++;
   if ((p = SBinetHttpUtils::getCookieValue(p, cookie->_Value)) == NULL)
   {
     if (logger) logger->Error(254, L"%s%S", L"cookiespec", cookiespec);
     goto failure;
   }
 
   p = SBinetHttpUtils::expectChar(p, ",;");
 
   if (p == NULL)
   {
     if (logger) logger->Error(255, L"%s%S", L"cookiespec", cookiespec);
     goto failure;
   }
 
   if (*p)
   {
     p = cookie->parseAttributes(p, logger);
     if (p == NULL)
       goto failure;
   }
 
   if (cookie->_Domain.length() == 0)
     cookie->_Domain = url->getHost();
 
   if (cookie->_Path.length() == 0)
   {
     const VXIchar *urlPath = url->getPath();
     const VXIchar *lastSlash = wcsrchr(urlPath, L'/');
     if (!lastSlash || lastSlash == urlPath)
     {
       cookie->_Path = "/";
 
     }
     else
     {
       cookie->_Path.clear();
       cookie->_Path.append(urlPath, lastSlash - urlPath);
     }
   }
 
   if (logger && logger->DiagIsEnabled(MODULE_SBINET_COOKIE_TAGID))
   {
     char expStr[64];
     logger->Diag(MODULE_SBINET_COOKIE_TAGID, L"SBinetCookie::parse",
 		 L"cookie-spec = '%S', name = '%S', value = '%S', "
 		 L"domain = '%S', path = '%S', expires = %S (%d), "
 		 L"secure = %s",
 		 cookiespec, cookie->_Name.c_str(), cookie->_Value.c_str(),
 		 cookie->_Domain.c_str(), cookie->_Path.c_str(),
 		 SBinetUtils::getTimeStampStr(cookie->_nExpires, expStr),
 		 cookie->_nExpires, (cookie->_fSecure ? L"true" : L"false"));
   }
 
   cookiespec = p;
 
   return cookie;
 
  failure:
   delete cookie;
   cookiespec = NULL;
   return NULL;
 }
 
 SBinetCookie::AttributeInfo SBinetCookie::attributeInfoMap[] = {
   { "path", true, pathHandler },
   { "domain", true, domainHandler },
   { "expires", true, expiresHandler },
   { "secure", false, secureHandler },
   { "max-age", true, maxAgeHandler }
 };
 
 void SBinetCookie::domainHandler(AttributeInfo *info, const char *value,
                                  SBinetCookie *cookie,
                                  const SWIutilLogger *logger)
 {
   cookie->_Domain = value;
 }
 
 void SBinetCookie::pathHandler(AttributeInfo *info, const char *value,
                                SBinetCookie *cookie,
                                const SWIutilLogger *logger)
 {
   cookie->_Path = value;
 
   // remove trailing slash if not the only character in the path.
   int len = cookie->_Path.length();
 
   if (len == 0)
     cookie->_Path = "/";
   else if (--len > 0 && cookie->_Path[len] == '/')
     cookie->_Path.resize(len);
 }
 
 void SBinetCookie::expiresHandler(AttributeInfo *info, const char *value,
                                   SBinetCookie *cookie,
                                   const SWIutilLogger *logger)
 {
   cookie->_nExpires = ap_parseHTTPdate(value);
 }
 
 void SBinetCookie::secureHandler(AttributeInfo *info, const char *value,
                                  SBinetCookie *cookie,
                                  const SWIutilLogger *logger)
 {
   cookie->_fSecure = true;
 }
 
 void SBinetCookie::maxAgeHandler(AttributeInfo *info, const char *value,
                                  SBinetCookie *cookie,
                                  const SWIutilLogger *logger)
 {
   cookie->_nExpires = time(NULL) + atoi(value);
 }
 
 const char *SBinetCookie::parseAttributes(const char *attributeSpec,
                                           const SWIutilLogger *logger)
 {
   const char *p = attributeSpec;
   for (;;)
   {
     while (*p && ap_isspace(*p)) p++;
 
     // end of cookie string.
     if (!*p || *p == ',') break;
 
     if (*p == ';')
     {
       // empty attribute.
       p++;
       continue;
     }
 
     attributeSpec = p;
 
     SBinetNString attributeNStr;
 
     if ((p = SBinetHttpUtils::getToken(p, attributeNStr)) == NULL)
     {
       if (logger)
         logger->Error(256, L"%s%S", L"attributeSpec", attributeSpec);
       return NULL;
     }
 
     const char *attribute = attributeNStr.c_str();
     AttributeInfo *info = NULL;
 
     for (int i = (sizeof (attributeInfoMap)) / (sizeof (attributeInfoMap[0])) - 1; i >= 0; i--)
     {
       if (strcasecmp(attributeInfoMap[i].name, attribute) == 0)
       {
         info = &attributeInfoMap[i];
         break;
       }
     }
 
     // If we haven't found a matching attributeInfo, we assume that the
     // attribute has a value.
     bool hasValue = info != NULL ? info->hasValue : true;
     SBinetNString valueNStr;
     const char *value = NULL;
 
     if (hasValue)
     {
       // Now we have to deal with attributes of the form x=y
       if ((p = SBinetHttpUtils::expectChar(p,"=")) == NULL || !*p)
       {
         if (logger)
           logger->Error(257, L"%s%S%s%S", L"attributeSpec", attributeSpec,
                         L"attribute", attribute);
         return NULL;
       }
 
       p++;
       if ((p = SBinetHttpUtils::getCookieValue(p, valueNStr)) == NULL)
       {
         if (logger)
           logger->Error(258, L"%s%S%s%S", L"attributeSpec", attributeSpec,
                         L"attribute", attribute);
         return NULL;
       }
       p = SBinetHttpUtils::expectChar(p, ",;");
 
       value = valueNStr.c_str();
 
       if (p == NULL)
       {
         if (logger)
           logger->Error(259, L"%s%S%s%S%s%S",
                         L"attributeSpec", attributeSpec,
                         L"attribute", attribute, L"value", value);
         return NULL;
       }
       if (logger)
         logger->Diag(MODULE_SBINET_COOKIE_TAGID,
                      L"SBinetCookie::parseAttributes",
                      L"attribute = <%S>. value = <%S>", attribute, value);
     }
     else
     {
       p = SBinetHttpUtils::expectChar(p, ",;");
 
       if (p == NULL)
       {
         if (logger)
           logger->Error(260, L"%s%S%s%S",
                         L"attributeSpec", attributeSpec,
                         L"attribute", attribute);
         return NULL;
       }
       if (*p && *p != ',' && *p != ';' && logger)
       {
         logger->Error(261, L"%s%S%s%S", L"attributeSpec", attributeSpec,
                       L"attribute", attribute);
       }
     }
     if (info != NULL)
     {
       info->handler(info, value, this, logger);
     }
   }
 
   return p;
 }


#endif

⌨️ 快捷键说明

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