зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1542293 - Rewrite various nsHttpResponseHead::Get* to use Tokenizer r=valentin,mayhemer,necko-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D69353
This commit is contained in:
Родитель
b494157695
Коммит
fd27762dce
|
@ -17,8 +17,13 @@ CacheControlParser::CacheControlParser(nsACString const& aHeader)
|
|||
mMaxStale(0),
|
||||
mMinFreshSet(false),
|
||||
mMinFresh(0),
|
||||
mStaleWhileRevalidateSet(false),
|
||||
mStaleWhileRevalidate(0),
|
||||
mNoCache(false),
|
||||
mNoStore(false) {
|
||||
mNoStore(false),
|
||||
mPublic(false),
|
||||
mPrivate(false),
|
||||
mImmutable(false) {
|
||||
SkipWhites();
|
||||
if (!CheckEOF()) {
|
||||
Directive();
|
||||
|
@ -37,6 +42,14 @@ void CacheControlParser::Directive() {
|
|||
mMaxStaleSet = SecondsValue(&mMaxStale, PR_UINT32_MAX);
|
||||
} else if (CheckWord("min-fresh")) {
|
||||
mMinFreshSet = SecondsValue(&mMinFresh);
|
||||
} else if (CheckWord("stale-while-revalidate")) {
|
||||
mStaleWhileRevalidateSet = SecondsValue(&mStaleWhileRevalidate);
|
||||
} else if (CheckWord("public")) {
|
||||
mPublic = true;
|
||||
} else if (CheckWord("private")) {
|
||||
mPrivate = true;
|
||||
} else if (CheckWord("immutable")) {
|
||||
mImmutable = true;
|
||||
} else {
|
||||
IgnoreDirective();
|
||||
}
|
||||
|
@ -103,9 +116,20 @@ bool CacheControlParser::MinFresh(uint32_t* seconds) {
|
|||
return mMinFreshSet;
|
||||
}
|
||||
|
||||
bool CacheControlParser::StaleWhileRevalidate(uint32_t* seconds) {
|
||||
*seconds = mStaleWhileRevalidate;
|
||||
return mStaleWhileRevalidateSet;
|
||||
}
|
||||
|
||||
bool CacheControlParser::NoCache() { return mNoCache; }
|
||||
|
||||
bool CacheControlParser::NoStore() { return mNoStore; }
|
||||
|
||||
bool CacheControlParser::Public() { return mPublic; }
|
||||
|
||||
bool CacheControlParser::Private() { return mPrivate; }
|
||||
|
||||
bool CacheControlParser::Immutable() { return mImmutable; }
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -19,8 +19,12 @@ class CacheControlParser final : Tokenizer {
|
|||
[[nodiscard]] bool MaxAge(uint32_t* seconds);
|
||||
[[nodiscard]] bool MaxStale(uint32_t* seconds);
|
||||
[[nodiscard]] bool MinFresh(uint32_t* seconds);
|
||||
[[nodiscard]] bool StaleWhileRevalidate(uint32_t* seconds);
|
||||
bool NoCache();
|
||||
bool NoStore();
|
||||
bool Public();
|
||||
bool Private();
|
||||
bool Immutable();
|
||||
|
||||
private:
|
||||
void Directive();
|
||||
|
@ -33,8 +37,13 @@ class CacheControlParser final : Tokenizer {
|
|||
uint32_t mMaxStale;
|
||||
bool mMinFreshSet;
|
||||
uint32_t mMinFresh;
|
||||
bool mStaleWhileRevalidateSet;
|
||||
uint32_t mStaleWhileRevalidate;
|
||||
bool mNoCache;
|
||||
bool mNoStore;
|
||||
bool mPublic;
|
||||
bool mPrivate;
|
||||
bool mImmutable;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "prtime.h"
|
||||
#include "plstr.h"
|
||||
#include "nsURLHelper.h"
|
||||
#include "CacheControlParser.h"
|
||||
#include <algorithm>
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -41,6 +42,11 @@ nsHttpResponseHead::nsHttpResponseHead(const nsHttpResponseHead& aOther)
|
|||
mCacheControlNoStore = other.mCacheControlNoStore;
|
||||
mCacheControlNoCache = other.mCacheControlNoCache;
|
||||
mCacheControlImmutable = other.mCacheControlImmutable;
|
||||
mCacheControlStaleWhileRevalidateSet =
|
||||
other.mCacheControlStaleWhileRevalidateSet;
|
||||
mCacheControlStaleWhileRevalidate = other.mCacheControlStaleWhileRevalidate;
|
||||
mCacheControlMaxAgeSet = other.mCacheControlMaxAgeSet;
|
||||
mCacheControlMaxAge = other.mCacheControlMaxAge;
|
||||
mPragmaNoCache = other.mPragmaNoCache;
|
||||
}
|
||||
|
||||
|
@ -62,6 +68,11 @@ nsHttpResponseHead& nsHttpResponseHead::operator=(
|
|||
mCacheControlNoStore = other.mCacheControlNoStore;
|
||||
mCacheControlNoCache = other.mCacheControlNoCache;
|
||||
mCacheControlImmutable = other.mCacheControlImmutable;
|
||||
mCacheControlStaleWhileRevalidateSet =
|
||||
other.mCacheControlStaleWhileRevalidateSet;
|
||||
mCacheControlStaleWhileRevalidate = other.mCacheControlStaleWhileRevalidate;
|
||||
mCacheControlMaxAgeSet = other.mCacheControlMaxAgeSet;
|
||||
mCacheControlMaxAge = other.mCacheControlMaxAge;
|
||||
mPragmaNoCache = other.mPragmaNoCache;
|
||||
|
||||
return *this;
|
||||
|
@ -782,22 +793,16 @@ bool nsHttpResponseHead::MustValidateIfExpired() {
|
|||
|
||||
bool nsHttpResponseHead::StaleWhileRevalidate(uint32_t now,
|
||||
uint32_t expiration) {
|
||||
nsresult rv;
|
||||
RecursiveMutexAutoLock monitor(mRecursiveMutex);
|
||||
|
||||
if (expiration <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t revalidateWindow;
|
||||
rv = GetStaleWhileRevalidateValue(&revalidateWindow);
|
||||
if (NS_FAILED(rv)) {
|
||||
if (expiration <= 0 || !mCacheControlStaleWhileRevalidateSet) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 'expiration' is the expiration time (an absolute unit), the swr window
|
||||
// extends the expiration time.
|
||||
CheckedInt<uint32_t> stallValidUntil = expiration;
|
||||
stallValidUntil += revalidateWindow;
|
||||
stallValidUntil += mCacheControlStaleWhileRevalidate;
|
||||
if (!stallValidUntil.isValid()) {
|
||||
// overflow means an indefinite stale window
|
||||
return true;
|
||||
|
@ -901,6 +906,10 @@ void nsHttpResponseHead::Reset() {
|
|||
mCacheControlNoStore = false;
|
||||
mCacheControlNoCache = false;
|
||||
mCacheControlImmutable = false;
|
||||
mCacheControlStaleWhileRevalidateSet = false;
|
||||
mCacheControlStaleWhileRevalidate = 0;
|
||||
mCacheControlMaxAgeSet = false;
|
||||
mCacheControlMaxAge = 0;
|
||||
mPragmaNoCache = false;
|
||||
mStatusText.Truncate();
|
||||
mContentType.Truncate();
|
||||
|
@ -941,59 +950,11 @@ nsresult nsHttpResponseHead::GetMaxAgeValue(uint32_t* result) {
|
|||
}
|
||||
|
||||
nsresult nsHttpResponseHead::GetMaxAgeValue_locked(uint32_t* result) const {
|
||||
const char* val = mHeaders.PeekHeader(nsHttp::Cache_Control);
|
||||
if (!val) return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
const char* p = nsHttp::FindToken(val, "max-age", HTTP_HEADER_VALUE_SEPS "=");
|
||||
if (!p) return NS_ERROR_NOT_AVAILABLE;
|
||||
p += 7;
|
||||
while (*p == ' ' || *p == '\t') ++p;
|
||||
if (*p != '=') return NS_ERROR_NOT_AVAILABLE;
|
||||
++p;
|
||||
while (*p == ' ' || *p == '\t') ++p;
|
||||
|
||||
int maxAgeValue = atoi(p);
|
||||
if (maxAgeValue < 0) maxAgeValue = 0;
|
||||
*result = static_cast<uint32_t>(maxAgeValue);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Get the stale-while-revalidate directive value, if present
|
||||
nsresult nsHttpResponseHead::GetStaleWhileRevalidateValue(uint32_t* result) {
|
||||
RecursiveMutexAutoLock monitor(mRecursiveMutex);
|
||||
return GetStaleWhileRevalidateValue_locked(result);
|
||||
}
|
||||
|
||||
nsresult nsHttpResponseHead::GetStaleWhileRevalidateValue_locked(
|
||||
uint32_t* result) const {
|
||||
const char* val = mHeaders.PeekHeader(nsHttp::Cache_Control);
|
||||
if (!val) {
|
||||
if (!mCacheControlMaxAgeSet) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
// Rewrite (best all FindToken users) to mozilla::Tokenizer, bug 1542293.
|
||||
const char* p = nsHttp::FindToken(val, "stale-while-revalidate",
|
||||
HTTP_HEADER_VALUE_SEPS "=");
|
||||
if (!p) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
p += 22;
|
||||
while (*p == ' ' || *p == '\t') {
|
||||
++p;
|
||||
}
|
||||
if (*p != '=') {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
++p;
|
||||
while (*p == ' ' || *p == '\t') {
|
||||
++p;
|
||||
}
|
||||
|
||||
int revalidateWindow = atoi(p);
|
||||
if (revalidateWindow < 0) {
|
||||
revalidateWindow = 0;
|
||||
}
|
||||
*result = static_cast<uint32_t>(revalidateWindow);
|
||||
*result = mCacheControlMaxAge;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1048,6 +1009,12 @@ bool nsHttpResponseHead::operator==(const nsHttpResponseHead& aOther) const {
|
|||
mCacheControlNoCache == aOther.mCacheControlNoCache &&
|
||||
mCacheControlNoStore == aOther.mCacheControlNoStore &&
|
||||
mCacheControlImmutable == aOther.mCacheControlImmutable &&
|
||||
mCacheControlStaleWhileRevalidateSet ==
|
||||
aOther.mCacheControlStaleWhileRevalidateSet &&
|
||||
mCacheControlStaleWhileRevalidate ==
|
||||
aOther.mCacheControlStaleWhileRevalidate &&
|
||||
mCacheControlMaxAgeSet == aOther.mCacheControlMaxAgeSet &&
|
||||
mCacheControlMaxAge == aOther.mCacheControlMaxAge &&
|
||||
mPragmaNoCache == aOther.mPragmaNoCache;
|
||||
}
|
||||
|
||||
|
@ -1153,31 +1120,25 @@ void nsHttpResponseHead::ParseCacheControl(const char* val) {
|
|||
mCacheControlNoCache = false;
|
||||
mCacheControlNoStore = false;
|
||||
mCacheControlImmutable = false;
|
||||
mCacheControlStaleWhileRevalidateSet = false;
|
||||
mCacheControlStaleWhileRevalidate = 0;
|
||||
mCacheControlMaxAgeSet = false;
|
||||
mCacheControlMaxAge = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// search header value for occurrence of "public"
|
||||
if (nsHttp::FindToken(val, "public", HTTP_HEADER_VALUE_SEPS)) {
|
||||
mCacheControlPublic = true;
|
||||
}
|
||||
nsDependentCString cacheControlRequestHeader(val);
|
||||
CacheControlParser cacheControlRequest(cacheControlRequestHeader);
|
||||
|
||||
// search header value for occurrence of "private"
|
||||
if (nsHttp::FindToken(val, "private", HTTP_HEADER_VALUE_SEPS))
|
||||
mCacheControlPrivate = true;
|
||||
|
||||
// search header value for occurrence(s) of "no-cache" but ignore
|
||||
// occurrence(s) of "no-cache=blah"
|
||||
if (nsHttp::FindToken(val, "no-cache", HTTP_HEADER_VALUE_SEPS))
|
||||
mCacheControlNoCache = true;
|
||||
|
||||
// search header value for occurrence of "no-store"
|
||||
if (nsHttp::FindToken(val, "no-store", HTTP_HEADER_VALUE_SEPS))
|
||||
mCacheControlNoStore = true;
|
||||
|
||||
// search header value for occurrence of "immutable"
|
||||
if (nsHttp::FindToken(val, "immutable", HTTP_HEADER_VALUE_SEPS)) {
|
||||
mCacheControlImmutable = true;
|
||||
}
|
||||
mCacheControlPublic = cacheControlRequest.Public();
|
||||
mCacheControlPrivate = cacheControlRequest.Private();
|
||||
mCacheControlNoCache = cacheControlRequest.NoCache();
|
||||
mCacheControlNoStore = cacheControlRequest.NoStore();
|
||||
mCacheControlImmutable = cacheControlRequest.Immutable();
|
||||
mCacheControlStaleWhileRevalidateSet =
|
||||
cacheControlRequest.StaleWhileRevalidate(
|
||||
&mCacheControlStaleWhileRevalidate);
|
||||
mCacheControlMaxAgeSet = cacheControlRequest.MaxAge(&mCacheControlMaxAge);
|
||||
}
|
||||
|
||||
void nsHttpResponseHead::ParsePragma(const char* val) {
|
||||
|
|
|
@ -47,6 +47,10 @@ class nsHttpResponseHead {
|
|||
mCacheControlNoStore(false),
|
||||
mCacheControlNoCache(false),
|
||||
mCacheControlImmutable(false),
|
||||
mCacheControlStaleWhileRevalidateSet(false),
|
||||
mCacheControlStaleWhileRevalidate(0),
|
||||
mCacheControlMaxAgeSet(false),
|
||||
mCacheControlMaxAge(0),
|
||||
mPragmaNoCache(false),
|
||||
mRecursiveMutex("nsHttpResponseHead.mRecursiveMutex"),
|
||||
mInVisitHeaders(false) {}
|
||||
|
@ -202,6 +206,10 @@ class nsHttpResponseHead {
|
|||
bool mCacheControlNoStore;
|
||||
bool mCacheControlNoCache;
|
||||
bool mCacheControlImmutable;
|
||||
bool mCacheControlStaleWhileRevalidateSet;
|
||||
uint32_t mCacheControlStaleWhileRevalidate;
|
||||
bool mCacheControlMaxAgeSet;
|
||||
uint32_t mCacheControlMaxAge;
|
||||
bool mPragmaNoCache;
|
||||
|
||||
// We are using RecursiveMutex instead of a Mutex because VisitHeader
|
||||
|
|
|
@ -43,7 +43,7 @@ function test_handler(metadata, response) {
|
|||
|
||||
function cached_handler(metadata, response) {
|
||||
response.setHeader("Content-Type", "text/plain");
|
||||
response.setHeader("Cache-Control", "Cache-Control: max-age=3600");
|
||||
response.setHeader("Cache-Control", "max-age=3600");
|
||||
response.setHeader("ETag", "test-etag1");
|
||||
|
||||
response.setStatusLine(metadata.httpVersion, 200, "OK");
|
||||
|
|
Загрузка…
Ссылка в новой задаче