зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1539003 - update InternalHeaders get/set/append/delete to match the spec; r=hsivonen
update Fetch InternalHeaders get/set/append/delete to match the spec Differential Revision: https://phabricator.services.mozilla.com/D27531 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
fe7c7d5fb8
Коммит
80259dac21
|
@ -40,40 +40,151 @@ void InternalHeaders::ToIPC(nsTArray<HeadersEntry>& aIPCHeaders,
|
|||
}
|
||||
}
|
||||
|
||||
bool InternalHeaders::IsValidHeaderValue(const nsCString& aLowerName,
|
||||
const nsCString& aNormalizedValue,
|
||||
ErrorResult& aRv) {
|
||||
// Steps 2 to 6 for ::Set() and ::Append() in the spec.
|
||||
|
||||
// Step 2
|
||||
if (IsInvalidName(aLowerName, aRv) || IsInvalidValue(aNormalizedValue, aRv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Step 3
|
||||
if (IsImmutable(aRv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Step 4
|
||||
if (mGuard == HeadersGuardEnum::Request &&
|
||||
IsForbiddenRequestHeader(aLowerName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Step 5
|
||||
if (mGuard == HeadersGuardEnum::Request_no_cors) {
|
||||
nsAutoCString tempValue;
|
||||
Get(aLowerName, tempValue, aRv);
|
||||
|
||||
if (tempValue.IsVoid()) {
|
||||
tempValue = aNormalizedValue;
|
||||
} else {
|
||||
tempValue.Append(", ");
|
||||
tempValue.Append(aNormalizedValue);
|
||||
}
|
||||
|
||||
if (!nsContentUtils::IsCORSSafelistedRequestHeader(aLowerName, tempValue)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Step 6
|
||||
else if (IsForbiddenResponseHeader(aLowerName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void InternalHeaders::Append(const nsACString& aName, const nsACString& aValue,
|
||||
ErrorResult& aRv) {
|
||||
nsAutoCString lowerName;
|
||||
ToLowerCase(aName, lowerName);
|
||||
// Step 1
|
||||
nsAutoCString trimValue;
|
||||
NS_TrimHTTPWhitespace(aValue, trimValue);
|
||||
|
||||
if (IsInvalidMutableHeader(lowerName, trimValue, aRv)) {
|
||||
// Steps 2 to 6
|
||||
nsAutoCString lowerName;
|
||||
ToLowerCase(aName, lowerName);
|
||||
if (!IsValidHeaderValue(lowerName, trimValue, aRv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 7
|
||||
nsAutoCString name(aName);
|
||||
ReuseExistingNameIfExists(name);
|
||||
|
||||
SetListDirty();
|
||||
|
||||
mList.AppendElement(Entry(name, trimValue));
|
||||
|
||||
// Step 8
|
||||
if (mGuard == HeadersGuardEnum::Request_no_cors) {
|
||||
RemovePrivilegedNoCorsRequestHeaders();
|
||||
}
|
||||
}
|
||||
|
||||
void InternalHeaders::RemovePrivilegedNoCorsRequestHeaders() {
|
||||
bool dirty = false;
|
||||
|
||||
// remove in reverse order to minimize copying
|
||||
for (int32_t i = mList.Length() - 1; i >= 0; --i) {
|
||||
if (IsPrivilegedNoCorsRequestHeaderName(mList[i].mName)) {
|
||||
mList.RemoveElementAt(i);
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (dirty) {
|
||||
SetListDirty();
|
||||
}
|
||||
}
|
||||
|
||||
bool InternalHeaders::DeleteInternal(const nsCString& aLowerName,
|
||||
ErrorResult& aRv) {
|
||||
bool dirty = false;
|
||||
|
||||
// remove in reverse order to minimize copying
|
||||
for (int32_t i = mList.Length() - 1; i >= 0; --i) {
|
||||
if (mList[i].mName.EqualsIgnoreCase(aLowerName.get())) {
|
||||
mList.RemoveElementAt(i);
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (dirty) {
|
||||
SetListDirty();
|
||||
}
|
||||
|
||||
return dirty;
|
||||
}
|
||||
|
||||
void InternalHeaders::Delete(const nsACString& aName, ErrorResult& aRv) {
|
||||
nsAutoCString lowerName;
|
||||
ToLowerCase(aName, lowerName);
|
||||
|
||||
if (IsInvalidMutableHeader(lowerName, aRv)) {
|
||||
// Step 1
|
||||
if (IsInvalidName(lowerName, aRv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetListDirty();
|
||||
// Step 2
|
||||
if (IsImmutable(aRv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// remove in reverse order to minimize copying
|
||||
for (int32_t i = mList.Length() - 1; i >= 0; --i) {
|
||||
if (mList[i].mName.EqualsIgnoreCase(lowerName.get())) {
|
||||
mList.RemoveElementAt(i);
|
||||
}
|
||||
// Step 3
|
||||
if (IsForbiddenRequestHeader(lowerName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 4
|
||||
if (mGuard == HeadersGuardEnum::Request_no_cors &&
|
||||
!IsNoCorsSafelistedRequestHeaderName(lowerName) &&
|
||||
!IsPrivilegedNoCorsRequestHeaderName(lowerName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 5
|
||||
if (IsForbiddenResponseHeader(lowerName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Steps 6 and 7
|
||||
if (!DeleteInternal(lowerName, aRv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 8
|
||||
if (mGuard == HeadersGuardEnum::Request_no_cors) {
|
||||
RemovePrivilegedNoCorsRequestHeaders();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,11 +197,16 @@ void InternalHeaders::Get(const nsACString& aName, nsACString& aValue,
|
|||
return;
|
||||
}
|
||||
|
||||
GetInternal(lowerName, aValue, aRv);
|
||||
}
|
||||
|
||||
void InternalHeaders::GetInternal(const nsCString& aLowerName,
|
||||
nsACString& aValue, ErrorResult& aRv) const {
|
||||
const char* delimiter = ", ";
|
||||
bool firstValueFound = false;
|
||||
|
||||
for (uint32_t i = 0; i < mList.Length(); ++i) {
|
||||
if (mList[i].mName.EqualsIgnoreCase(lowerName.get())) {
|
||||
if (mList[i].mName.EqualsIgnoreCase(aLowerName.get())) {
|
||||
if (firstValueFound) {
|
||||
aValue += delimiter;
|
||||
}
|
||||
|
@ -143,15 +259,18 @@ bool InternalHeaders::Has(const nsACString& aName, ErrorResult& aRv) const {
|
|||
|
||||
void InternalHeaders::Set(const nsACString& aName, const nsACString& aValue,
|
||||
ErrorResult& aRv) {
|
||||
nsAutoCString lowerName;
|
||||
ToLowerCase(aName, lowerName);
|
||||
// Step 1
|
||||
nsAutoCString trimValue;
|
||||
NS_TrimHTTPWhitespace(aValue, trimValue);
|
||||
|
||||
if (IsInvalidMutableHeader(lowerName, trimValue, aRv)) {
|
||||
// Steps 2 to 6
|
||||
nsAutoCString lowerName;
|
||||
ToLowerCase(aName, lowerName);
|
||||
if (!IsValidHeaderValue(lowerName, trimValue, aRv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 7
|
||||
SetListDirty();
|
||||
|
||||
int32_t firstIndex = INT32_MAX;
|
||||
|
@ -171,6 +290,11 @@ void InternalHeaders::Set(const nsACString& aName, const nsACString& aValue,
|
|||
} else {
|
||||
mList.AppendElement(Entry(aName, trimValue));
|
||||
}
|
||||
|
||||
// Step 8
|
||||
if (mGuard == HeadersGuardEnum::Request_no_cors) {
|
||||
RemovePrivilegedNoCorsRequestHeaders();
|
||||
}
|
||||
}
|
||||
|
||||
void InternalHeaders::Clear() {
|
||||
|
@ -186,6 +310,21 @@ void InternalHeaders::SetGuard(HeadersGuardEnum aGuard, ErrorResult& aRv) {
|
|||
|
||||
InternalHeaders::~InternalHeaders() {}
|
||||
|
||||
// static
|
||||
bool InternalHeaders::IsNoCorsSafelistedRequestHeaderName(
|
||||
const nsCString& aName) {
|
||||
return aName.EqualsIgnoreCase("accept") ||
|
||||
aName.EqualsIgnoreCase("accept-language") ||
|
||||
aName.EqualsIgnoreCase("content-language") ||
|
||||
aName.EqualsIgnoreCase("content-type");
|
||||
}
|
||||
|
||||
// static
|
||||
bool InternalHeaders::IsPrivilegedNoCorsRequestHeaderName(
|
||||
const nsCString& aName) {
|
||||
return aName.EqualsIgnoreCase("range");
|
||||
}
|
||||
|
||||
// static
|
||||
bool InternalHeaders::IsSimpleHeader(const nsCString& aName,
|
||||
const nsACString& aValue) {
|
||||
|
@ -376,8 +515,8 @@ already_AddRefed<InternalHeaders> InternalHeaders::CORSHeaders(
|
|||
ErrorResult result;
|
||||
|
||||
nsAutoCString acExposedNames;
|
||||
aHeaders->GetFirst(NS_LITERAL_CSTRING("Access-Control-Expose-Headers"),
|
||||
acExposedNames, result);
|
||||
aHeaders->Get(NS_LITERAL_CSTRING("Access-Control-Expose-Headers"),
|
||||
acExposedNames, result);
|
||||
MOZ_ASSERT(!result.Failed());
|
||||
|
||||
AutoTArray<nsCString, 5> exposeNamesArray;
|
||||
|
|
|
@ -124,6 +124,8 @@ class InternalHeaders final {
|
|||
|
||||
static bool IsInvalidName(const nsACString& aName, ErrorResult& aRv);
|
||||
static bool IsInvalidValue(const nsACString& aValue, ErrorResult& aRv);
|
||||
bool IsValidHeaderValue(const nsCString& aLowerName,
|
||||
const nsCString& aNormalizedValue, ErrorResult& aRv);
|
||||
bool IsImmutable(ErrorResult& aRv) const;
|
||||
bool IsForbiddenRequestHeader(const nsCString& aName) const;
|
||||
bool IsForbiddenRequestNoCorsHeader(const nsCString& aName) const;
|
||||
|
@ -147,6 +149,17 @@ class InternalHeaders final {
|
|||
// with the same name (ignoring case, per the spec).
|
||||
void ReuseExistingNameIfExists(nsCString& aName) const;
|
||||
|
||||
void RemovePrivilegedNoCorsRequestHeaders();
|
||||
|
||||
void GetInternal(const nsCString& aLowerName, nsACString& aValue,
|
||||
ErrorResult& aRv) const;
|
||||
|
||||
bool DeleteInternal(const nsCString& aLowerName, ErrorResult& aRv);
|
||||
|
||||
static bool IsNoCorsSafelistedRequestHeaderName(const nsCString& aName);
|
||||
|
||||
static bool IsPrivilegedNoCorsRequestHeaderName(const nsCString& aName);
|
||||
|
||||
static bool IsSimpleHeader(const nsCString& aName, const nsACString& aValue);
|
||||
|
||||
static bool IsRevalidationHeader(const nsCString& aName);
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
[headers-no-cors.window.html]
|
||||
["no-cors" Headers object cannot have content-type set to text/plain;ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss, text/plain]
|
||||
expected: FAIL
|
||||
|
||||
["no-cors" Headers object cannot have accept set to sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss, , sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss]
|
||||
expected: FAIL
|
||||
|
||||
["no-cors" Headers object cannot have accept-language set to sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss, , sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss]
|
||||
expected: FAIL
|
||||
|
||||
["no-cors" Headers object cannot have content-language set to sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss, , sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss]
|
||||
expected: FAIL
|
||||
|
||||
["no-cors" Headers object cannot have content-language set to , sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss]
|
||||
expected: FAIL
|
||||
|
||||
["no-cors" Headers object cannot have accept-language set to , sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss]
|
||||
expected: FAIL
|
||||
|
||||
["no-cors" Headers object cannot have accept set to , sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss]
|
||||
expected: FAIL
|
||||
|
Загрузка…
Ссылка в новой задаче