📄 sbinetvalidator.cpp
字号:
Log(L"SBinetValidator::Deserialize");
return VXIinet_RESULT_SUCCESS;
}
VXIContent *SBinetValidator::serialize() const
{
VXIbyte *data = NULL;
VXIulong dataSize;
VXIContent *content;
if (serialize(data, dataSize))
{
// Create the content
content = VXIContentCreate(VALIDATOR_MIME_TYPE, data, dataSize,
ContentDestroy, NULL);
if (content == NULL)
delete [] data;
}
return content;
}
bool SBinetValidator::serialize(VXIbyte*& content, VXIulong& contentSize) const
{
// Pack the data
int urlLen = 0;
int eTagLen = 0;
contentSize = ((sizeof _refTime) +
(sizeof _freshnessLifetime) +
(sizeof _lastModified) +
(sizeof _mustRevalidateF) +
(sizeof _sizeBytes) +
(sizeof eTagLen) +
(sizeof urlLen));
if (_eTag != NULL)
{
eTagLen = ::wcslen(_eTag);
contentSize += eTagLen * sizeof(VXIchar);
}
if (_url != NULL)
{
urlLen = ::wcslen(_url);
contentSize += urlLen * sizeof(VXIchar);
}
content = new VXIbyte[contentSize];
VXIbyte *ptr = content;
::memcpy(ptr, &_refTime, sizeof _refTime);
ptr += sizeof _refTime;
::memcpy(ptr, &_freshnessLifetime, sizeof _freshnessLifetime);
ptr += sizeof _freshnessLifetime;
::memcpy(ptr, &_lastModified, sizeof _lastModified);
ptr += sizeof _lastModified;
::memcpy(ptr, &_mustRevalidateF, sizeof _mustRevalidateF);
ptr += sizeof _mustRevalidateF;
::memcpy(ptr, &_sizeBytes, sizeof _sizeBytes);
ptr += sizeof _sizeBytes;
::memcpy(ptr, &eTagLen, sizeof eTagLen);
ptr += sizeof eTagLen;
if (eTagLen > 0)
{
::memcpy(ptr, _eTag, eTagLen * sizeof(VXIchar));
ptr += eTagLen * sizeof(VXIchar);
}
::memcpy(ptr, &urlLen, sizeof urlLen);
ptr += sizeof urlLen;
if (urlLen > 0)
{
::memcpy(ptr, _url, urlLen * sizeof(VXIchar));
ptr += urlLen * sizeof(VXIchar);
}
return true;
}
time_t SBinetValidator::getExpiresTime() const
{
if (_freshnessLifetime <= (time_t) 0)
return (time_t) 0;
return _refTime + _freshnessLifetime;
}
bool SBinetValidator::isExpired() const
{
return _freshnessLifetime == (time_t) 0 ||
_freshnessLifetime < time(NULL) - _refTime;
}
bool SBinetValidator::isExpired(const VXIint maxAge,
const VXIint maxStale) const
{
if (maxAge == 0) return true;
time_t now = time(NULL);
time_t currentAge = now - _refTime;
if (maxAge > 0 && currentAge > maxAge) return true;
time_t staleness = currentAge - _freshnessLifetime;
if (staleness < 0) return false;
if (_mustRevalidateF) return true;
if (staleness > maxStale) return true;
if (_freshnessLifetime == (time_t) 0) return true;
return false;
}
bool SBinetValidator::isStrong() const
{
return _eTag != NULL && wcsncasecmp(_eTag, L"w/", 2) != 0;
}
void SBinetValidator::Log(const VXIchar *name) const
{
if (DiagIsEnabled(MODULE_SBINET_VALIDATOR_TAGID))
{
char refTimeStr[64], expireStr[64], lastModifiedStr[64];
if (_refTime == (time_t) -1)
::strcpy(refTimeStr, "-1");
else
SBinetUtils::getTimeStampStr(_refTime, refTimeStr);
SBinetUtils::getTimeStampStr(getExpiresTime(), expireStr);
if (_lastModified == (time_t) -1)
::strcpy(lastModifiedStr, "-1");
else
SBinetUtils::getTimeStampStr(_lastModified, lastModifiedStr);
Diag(MODULE_SBINET_VALIDATOR_TAGID, name,
L"URL: '%s', refTime %S, last modified %S, expires %S, must revalidate %s, size %lu, etag '%s'",
_url, refTimeStr, lastModifiedStr, expireStr,
_mustRevalidateF ? L"true" : L"false",
_sizeBytes, _eTag);
}
}
void SBinetValidator::ContentDestroy(VXIbyte **content, void *userData)
{
if (content)
{
delete [] *content;
*content = NULL;
}
}
time_t SBinetValidator::checkPragma(const VXIMap *streamInfo)
{
const VXIchar *pragmaDirective = SBinetUtils::getString(streamInfo, L"Pragma");
if (pragmaDirective == NULL)
{
Diag(MODULE_SBINET_VALIDATOR_TAGID, L"SBinetValidator::checkPragma",
L"No Pragma directive.");
return (time_t) -1;
}
Diag(MODULE_SBINET_VALIDATOR_TAGID, L"SBinetValidator::checkPragma",
L"Pragma directive: '%s'", pragmaDirective);
const VXIchar *p = pragmaDirective;
while (*p && SBinetHttpUtils::isSpace(*p)) p++;
if (wcsncasecmp(p, L"no-cache", 8) == 0)
{
Diag(MODULE_SBINET_VALIDATOR_TAGID, L"SBinetValidator::checkPragma",
L"Got Pragma: no-cache directive.");
return (time_t) 0;
}
return (time_t) -1;
}
time_t SBinetValidator::checkCacheControl(const VXIMap *streamInfo)
{
time_t maxAge = (time_t) -1;
const VXIchar *cacheControlDirective = SBinetUtils::getString(streamInfo, L"Cache-Control");
if (cacheControlDirective == NULL)
{
Diag(MODULE_SBINET_VALIDATOR_TAGID, L"SBinetValidator::checkCacheControl",
L"No Cache-Control directive.");
return maxAge;
}
// We need to convert to narrow string in order to take advantage of the
// HttpUtils function that are written in terms of narrow character.
SBinetNString tmp = cacheControlDirective;
const char *content = tmp.c_str();
Diag(MODULE_SBINET_VALIDATOR_TAGID, L"SBinetValidator::checkCacheControl",
L"Cache-Control directive: '%S'", content);
int priority = 0;
static const int maxAgePriority = 0;
static const int sMaxAgePriority = 1;
static const int cacheControlPriority = 2;
SBinetNString attrib;
SBinetNString val;
for (;;)
{
content = SBinetHttpUtils::getValue(content, attrib);
if (content == NULL)
{
Diag(MODULE_SBINET_VALIDATOR_TAGID,
L"SBinetValidator::checkCacheControl",
L"Could not get value.");
break;
}
content = SBinetHttpUtils::expectChar(content, "=,");
if (content == NULL)
{
Diag(MODULE_SBINET_VALIDATOR_TAGID,
L"SBinetValidator::checkCacheControl",
L"Expecting '=' or ','.");
break;
}
const char *attribute = attrib.c_str();
const char *value = NULL;
if (*content == '=')
{
content = SBinetHttpUtils::getValue(++content, val);
if (content == NULL)
{
Diag(MODULE_SBINET_VALIDATOR_TAGID,
L"SBinetValidator::checkCacheControl",
L"Could not extract value for attribute",
attribute);
break;
}
value = val.c_str();
}
Diag(MODULE_SBINET_VALIDATOR_TAGID, L"SBinetValidator::checkCacheControl",
L"attribute = '%S', value = '%S'", attribute, value);
if (strcasecmp(attribute, "no-cache") == 0)
{
// Ignore no-cache="something" as we have one cookie jar per channel.
// So they are not shared.
if (value == NULL && priority <= cacheControlPriority)
{
maxAge = (time_t) 0;
priority = cacheControlPriority;
}
}
else if ((strcasecmp(attribute, "no-store") == 0 ||
strcasecmp(attribute, "private") == 0)
&& priority <= cacheControlPriority)
{
maxAge = (time_t) 0;
priority = cacheControlPriority;
}
else if (strcasecmp(attribute, "must-revalidate") == 0)
{
// This directive does not affect priority nor does it depend on a
// priority as it does not modify the maxAge value.
_mustRevalidateF = true;
}
else if (strcasecmp(attribute, "max-age") == 0)
{
if (value != NULL && priority <= maxAgePriority)
{
maxAge = (time_t) atoi(value);
priority = maxAgePriority;
}
}
else if (strcasecmp(attribute, "s-maxage") == 0)
{
if (value != NULL && priority <= sMaxAgePriority)
{
maxAge = atoi(value);
priority = sMaxAgePriority;
}
}
content = SBinetHttpUtils::expectChar(content, ",");
if (content == NULL)
{
Diag(MODULE_SBINET_VALIDATOR_TAGID,
L"SBinetValidator::checkCacheControl",
L"Expecting ','.");
break;
}
if (!*content)
{
// end of string. No error.
break;
}
content++;
}
return maxAge;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -