Bug 1857841 - pt 3. Add a new page kind named "fresh" r=glandium
[gecko.git] / dom / fetch / InternalHeaders.h
blob4b43bc3db1aefbedda2388a46c5054cfdcd642f8
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"
18 class nsIRequest;
20 namespace mozilla {
22 class ErrorResult;
24 namespace dom {
26 template <typename K, typename V>
27 class Record;
28 class HeadersEntry;
30 class InternalHeaders final {
31 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(InternalHeaders)
33 public:
34 struct Entry {
35 Entry(const nsACString& aName, const nsACString& aValue)
36 : mName(aName), mValue(aValue) {}
38 Entry() = default;
40 nsCString mName;
41 nsCString mValue;
44 private:
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
52 // iterated.
53 bool mListDirty;
55 public:
56 explicit InternalHeaders(HeadersGuardEnum aGuard = HeadersGuardEnum::None)
57 : mGuard(aGuard), mListDirty(false) {}
59 explicit InternalHeaders(const InternalHeaders& aOther)
60 : mGuard(HeadersGuardEnum::None), mListDirty(true) {
61 ErrorResult result;
62 Fill(aOther, result);
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,
78 ErrorResult& aRv);
79 void Delete(const nsACString& aName, ErrorResult& aRv);
80 void Get(const nsACString& aName, nsACString& aValue, ErrorResult& aRv) const;
81 void GetSetCookie(nsTArray<nsCString>& aValues) const;
82 void GetFirst(const nsACString& aName, nsACString& aValue,
83 ErrorResult& aRv) const;
84 bool Has(const nsACString& aName, ErrorResult& aRv) const;
85 void Set(const nsACString& aName, const nsACString& aValue, ErrorResult& aRv);
87 uint32_t GetIterableLength() {
88 MaybeSortList();
89 return mSortedList.Length();
91 const NS_ConvertASCIItoUTF16 GetKeyAtIndex(unsigned aIndex) {
92 MaybeSortList();
93 MOZ_ASSERT(aIndex < mSortedList.Length());
94 return NS_ConvertASCIItoUTF16(mSortedList[aIndex].mName);
96 const NS_ConvertASCIItoUTF16 GetValueAtIndex(unsigned aIndex) {
97 MaybeSortList();
98 MOZ_ASSERT(aIndex < mSortedList.Length());
99 return NS_ConvertASCIItoUTF16(mSortedList[aIndex].mValue);
102 void Clear();
104 HeadersGuardEnum Guard() const { return mGuard; }
105 void SetGuard(HeadersGuardEnum aGuard, ErrorResult& aRv);
107 void Fill(const InternalHeaders& aInit, ErrorResult& aRv);
108 void Fill(const Sequence<Sequence<nsCString>>& aInit, ErrorResult& aRv);
109 void Fill(const Record<nsCString, nsCString>& aInit, ErrorResult& aRv);
110 void FillResponseHeaders(nsIRequest* aRequest);
112 bool HasOnlySimpleHeaders() const;
114 bool HasRevalidationHeaders() const;
116 static already_AddRefed<InternalHeaders> BasicHeaders(
117 InternalHeaders* aHeaders);
119 static already_AddRefed<InternalHeaders> CORSHeaders(
120 InternalHeaders* aHeaders,
121 RequestCredentials aCredentialsMode = RequestCredentials::Omit);
123 void GetEntries(nsTArray<InternalHeaders::Entry>& aEntries) const;
125 void GetUnsafeHeaders(nsTArray<nsCString>& aNames) const;
127 private:
128 virtual ~InternalHeaders();
130 static bool IsInvalidName(const nsACString& aName, ErrorResult& aRv);
131 static bool IsInvalidValue(const nsACString& aValue, ErrorResult& aRv);
132 bool IsValidHeaderValue(const nsCString& aLowerName,
133 const nsCString& aNormalizedValue, ErrorResult& aRv);
134 bool IsImmutable(ErrorResult& aRv) const;
135 bool IsForbiddenRequestHeader(const nsCString& aName,
136 const nsACString& aValue) const;
137 bool IsForbiddenRequestNoCorsHeader(const nsCString& aName) const;
138 bool IsForbiddenRequestNoCorsHeader(const nsCString& aName,
139 const nsACString& aValue) const;
140 bool IsForbiddenResponseHeader(const nsCString& aName) const;
142 bool IsInvalidMutableHeader(const nsCString& aName, ErrorResult& aRv) const {
143 return IsInvalidMutableHeader(aName, ""_ns, aRv);
146 bool IsInvalidMutableHeader(const nsCString& aName, const nsACString& aValue,
147 ErrorResult& aRv) const {
148 return IsInvalidName(aName, aRv) || IsInvalidValue(aValue, aRv) ||
149 IsImmutable(aRv) || IsForbiddenRequestHeader(aName, aValue) ||
150 IsForbiddenRequestNoCorsHeader(aName, aValue) ||
151 IsForbiddenResponseHeader(aName);
154 // This method updates the passed name to match the capitalization of a header
155 // with the same name (ignoring case, per the spec).
156 void ReuseExistingNameIfExists(nsCString& aName) const;
158 void RemovePrivilegedNoCorsRequestHeaders();
160 void GetInternal(const nsCString& aLowerName, nsACString& aValue,
161 ErrorResult& aRv) const;
163 bool DeleteInternal(const nsCString& aLowerName, ErrorResult& aRv);
165 static bool IsNoCorsSafelistedRequestHeaderName(const nsCString& aName);
167 static bool IsPrivilegedNoCorsRequestHeaderName(const nsCString& aName);
169 static bool IsRevalidationHeader(const nsCString& aName);
171 void MaybeSortList();
172 void SetListDirty();
175 } // namespace dom
176 } // namespace mozilla
178 #endif // mozilla_dom_InternalHeaders_h