mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-08 00:38:39 +09:00
[Network, DOM] Align our implementation with the current CORS/Fetch spec.
This commit is contained in:
parent
bf19c2087b
commit
37f0199c79
9 changed files with 366 additions and 31 deletions
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "mozilla/dom/InternalHeaders.h"
|
||||
|
||||
#include "FetchUtil.h"
|
||||
#include "mozilla/dom/FetchTypes.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
|
||||
|
|
@ -46,20 +47,112 @@ 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) {
|
||||
if (IsForbiddenRequestHeader(aLowerName, aNormalizedValue)) {
|
||||
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)
|
||||
{
|
||||
// Step 1
|
||||
nsAutoCString trimValue;
|
||||
NS_TrimHTTPWhitespace(aValue, trimValue);
|
||||
|
||||
// Steps 2 to 6
|
||||
nsAutoCString lowerName;
|
||||
ToLowerCase(aName, lowerName);
|
||||
|
||||
if (IsInvalidMutableHeader(lowerName, aValue, aRv)) {
|
||||
if (!IsValidHeaderValue(lowerName, trimValue, aRv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 7
|
||||
SetListDirty();
|
||||
|
||||
mList.AppendElement(Entry(lowerName, aValue));
|
||||
|
||||
// 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
|
||||
|
|
@ -68,17 +161,43 @@ 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 (lowerName == mList[i].mName) {
|
||||
mList.RemoveElementAt(i);
|
||||
}
|
||||
// Step 3
|
||||
nsAutoCString value;
|
||||
GetInternal(lowerName, value, aRv);
|
||||
if (IsForbiddenRequestHeader(lowerName, value)) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -91,12 +210,18 @@ InternalHeaders::Get(const nsACString& aName, nsACString& aValue, ErrorResult& a
|
|||
if (IsInvalidName(lowerName, aRv)) {
|
||||
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 (lowerName == mList[i].mName) {
|
||||
if (aLowerName == mList[i].mName) {
|
||||
if (firstValueFound) {
|
||||
aValue += delimiter;
|
||||
}
|
||||
|
|
@ -153,13 +278,18 @@ InternalHeaders::Has(const nsACString& aName, ErrorResult& aRv) const
|
|||
void
|
||||
InternalHeaders::Set(const nsACString& aName, const nsACString& aValue, ErrorResult& aRv)
|
||||
{
|
||||
// Step 1
|
||||
nsAutoCString trimValue;
|
||||
NS_TrimHTTPWhitespace(aValue, trimValue);
|
||||
|
||||
// Steps 2 to 6
|
||||
nsAutoCString lowerName;
|
||||
ToLowerCase(aName, lowerName);
|
||||
|
||||
if (IsInvalidMutableHeader(lowerName, aValue, aRv)) {
|
||||
if (!IsValidHeaderValue(lowerName, trimValue, aRv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 7
|
||||
SetListDirty();
|
||||
|
||||
int32_t firstIndex = INT32_MAX;
|
||||
|
|
@ -179,6 +309,11 @@ InternalHeaders::Set(const nsACString& aName, const nsACString& aValue, ErrorRes
|
|||
} else {
|
||||
mList.AppendElement(Entry(lowerName, aValue));
|
||||
}
|
||||
|
||||
// Step 8
|
||||
if (mGuard == HeadersGuardEnum::Request_no_cors) {
|
||||
RemovePrivilegedNoCorsRequestHeaders();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -200,6 +335,22 @@ 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 nsACString& aName, const nsACString& aValue)
|
||||
|
|
@ -207,9 +358,12 @@ InternalHeaders::IsSimpleHeader(const nsACString& aName, const nsACString& aValu
|
|||
// Note, we must allow a null content-type value here to support
|
||||
// get("content-type"), but the IsInvalidValue() check will prevent null
|
||||
// from being set or appended.
|
||||
return aName.EqualsLiteral("accept") ||
|
||||
aName.EqualsLiteral("accept-language") ||
|
||||
aName.EqualsLiteral("content-language") ||
|
||||
return (aName.EqualsLiteral("accept") &&
|
||||
nsContentUtils::IsAllowedNonCorsAccept(aValue)) ||
|
||||
(aName.EqualsLiteral("accept-language") &&
|
||||
nsContentUtils::IsAllowedNonCorsLanguage(aValue))||
|
||||
(aName.EqualsLiteral("content-language") &&
|
||||
nsContentUtils::IsAllowedNonCorsLanguage(aValue))||
|
||||
(aName.EqualsLiteral("content-type") &&
|
||||
nsContentUtils::IsAllowedNonCorsContentType(aValue));
|
||||
}
|
||||
|
|
@ -261,10 +415,11 @@ InternalHeaders::IsImmutable(ErrorResult& aRv) const
|
|||
}
|
||||
|
||||
bool
|
||||
InternalHeaders::IsForbiddenRequestHeader(const nsACString& aName) const
|
||||
InternalHeaders::IsForbiddenRequestHeader(const nsACString& aName,
|
||||
const nsACString& aValue) const
|
||||
{
|
||||
return mGuard == HeadersGuardEnum::Request &&
|
||||
nsContentUtils::IsForbiddenRequestHeader(aName);
|
||||
nsContentUtils::IsForbiddenRequestHeader(aName, aValue);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -370,7 +525,7 @@ InternalHeaders::CORSHeaders(InternalHeaders* aHeaders, RequestCredentials aCred
|
|||
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());
|
||||
|
||||
bool allowAllHeaders = false;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue