1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_InternalHeaders_h
8 #define mozilla_dom_InternalHeaders_h
10 // needed for HeadersGuardEnum.
11 #include "mozilla/dom/HeadersBinding.h"
12 #include "mozilla/dom/RequestBinding.h"
13 #include "mozilla/dom/UnionTypes.h"
15 #include "nsClassHashtable.h"
16 #include "nsWrapperCache.h"
26 template <typename K
, typename V
>
30 class InternalHeaders final
{
31 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(InternalHeaders
)
35 Entry(const nsACString
& aName
, const nsACString
& aValue
)
36 : mName(aName
), mValue(aValue
) {}
45 HeadersGuardEnum mGuard
;
46 nsTArray
<Entry
> mList
;
48 nsTArray
<Entry
> mSortedList
;
50 // This boolean is set to true at any writing operation to mList. It's set to
51 // false when mSortedList is regenerated. This happens when the header is
56 explicit InternalHeaders(HeadersGuardEnum aGuard
= HeadersGuardEnum::None
)
57 : mGuard(aGuard
), mListDirty(false) {}
59 explicit InternalHeaders(const InternalHeaders
& aOther
)
60 : mGuard(HeadersGuardEnum::None
), mListDirty(true) {
63 MOZ_ASSERT(!result
.Failed());
64 // Note that it's important to set the guard after Fill(), to make sure
65 // that Fill() doesn't fail if aOther is immutable.
66 mGuard
= aOther
.mGuard
;
69 explicit InternalHeaders(nsTArray
<Entry
>&& aHeaders
,
70 HeadersGuardEnum aGuard
= HeadersGuardEnum::None
);
72 InternalHeaders(const nsTArray
<HeadersEntry
>& aHeadersEntryList
,
73 HeadersGuardEnum aGuard
);
75 void ToIPC(nsTArray
<HeadersEntry
>& aIPCHeaders
, HeadersGuardEnum
& aGuard
);
77 void Append(const nsACString
& aName
, const nsACString
& aValue
,
79 void Delete(const nsACString
& aName
, ErrorResult
& aRv
);
80 void Get(const nsACString
& aName
, nsACString
& aValue
, ErrorResult
& aRv
) const;
81 void GetFirst(const nsACString
& aName
, nsACString
& aValue
,
82 ErrorResult
& aRv
) const;
83 bool Has(const nsACString
& aName
, ErrorResult
& aRv
) const;
84 void Set(const nsACString
& aName
, const nsACString
& aValue
, ErrorResult
& aRv
);
86 uint32_t GetIterableLength() {
88 return mSortedList
.Length();
90 const NS_ConvertASCIItoUTF16
GetKeyAtIndex(unsigned aIndex
) {
92 MOZ_ASSERT(aIndex
< mSortedList
.Length());
93 return NS_ConvertASCIItoUTF16(mSortedList
[aIndex
].mName
);
95 const NS_ConvertASCIItoUTF16
GetValueAtIndex(unsigned aIndex
) {
97 MOZ_ASSERT(aIndex
< mSortedList
.Length());
98 return NS_ConvertASCIItoUTF16(mSortedList
[aIndex
].mValue
);
103 HeadersGuardEnum
Guard() const { return mGuard
; }
104 void SetGuard(HeadersGuardEnum aGuard
, ErrorResult
& aRv
);
106 void Fill(const InternalHeaders
& aInit
, ErrorResult
& aRv
);
107 void Fill(const Sequence
<Sequence
<nsCString
>>& aInit
, ErrorResult
& aRv
);
108 void Fill(const Record
<nsCString
, nsCString
>& aInit
, ErrorResult
& aRv
);
109 void FillResponseHeaders(nsIRequest
* aRequest
);
111 bool HasOnlySimpleHeaders() const;
113 bool HasRevalidationHeaders() const;
115 static already_AddRefed
<InternalHeaders
> BasicHeaders(
116 InternalHeaders
* aHeaders
);
118 static already_AddRefed
<InternalHeaders
> CORSHeaders(
119 InternalHeaders
* aHeaders
,
120 RequestCredentials mCredentialsMode
= RequestCredentials::Omit
);
122 void GetEntries(nsTArray
<InternalHeaders::Entry
>& aEntries
) const;
124 void GetUnsafeHeaders(nsTArray
<nsCString
>& aNames
) const;
127 virtual ~InternalHeaders();
129 static bool IsInvalidName(const nsACString
& aName
, ErrorResult
& aRv
);
130 static bool IsInvalidValue(const nsACString
& aValue
, ErrorResult
& aRv
);
131 bool IsValidHeaderValue(const nsCString
& aLowerName
,
132 const nsCString
& aNormalizedValue
, ErrorResult
& aRv
);
133 bool IsImmutable(ErrorResult
& aRv
) const;
134 bool IsForbiddenRequestHeader(const nsCString
& aName
) const;
135 bool IsForbiddenRequestNoCorsHeader(const nsCString
& aName
) const;
136 bool IsForbiddenRequestNoCorsHeader(const nsCString
& aName
,
137 const nsACString
& aValue
) const;
138 bool IsForbiddenResponseHeader(const nsCString
& aName
) const;
140 bool IsInvalidMutableHeader(const nsCString
& aName
, ErrorResult
& aRv
) const {
141 return IsInvalidMutableHeader(aName
, ""_ns
, aRv
);
144 bool IsInvalidMutableHeader(const nsCString
& aName
, const nsACString
& aValue
,
145 ErrorResult
& aRv
) const {
146 return IsInvalidName(aName
, aRv
) || IsInvalidValue(aValue
, aRv
) ||
147 IsImmutable(aRv
) || IsForbiddenRequestHeader(aName
) ||
148 IsForbiddenRequestNoCorsHeader(aName
, aValue
) ||
149 IsForbiddenResponseHeader(aName
);
152 // This method updates the passed name to match the capitalization of a header
153 // with the same name (ignoring case, per the spec).
154 void ReuseExistingNameIfExists(nsCString
& aName
) const;
156 void RemovePrivilegedNoCorsRequestHeaders();
158 void GetInternal(const nsCString
& aLowerName
, nsACString
& aValue
,
159 ErrorResult
& aRv
) const;
161 bool DeleteInternal(const nsCString
& aLowerName
, ErrorResult
& aRv
);
163 static bool IsNoCorsSafelistedRequestHeaderName(const nsCString
& aName
);
165 static bool IsPrivilegedNoCorsRequestHeaderName(const nsCString
& aName
);
167 static bool IsSimpleHeader(const nsCString
& aName
, const nsACString
& aValue
);
169 static bool IsRevalidationHeader(const nsCString
& aName
);
171 void MaybeSortList();
176 } // namespace mozilla
178 #endif // mozilla_dom_InternalHeaders_h