📄 sbinetvalidator.cpp
字号:
_url = NULL; 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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -