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:
sonakshi 2020-04-23 17:11:44 +00:00
Родитель b494157695
Коммит fd27762dce
5 изменённых файлов: 84 добавлений и 82 удалений

Просмотреть файл

@ -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");