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