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 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() {
89 return mSortedList
.Length();
91 const NS_ConvertASCIItoUTF16
GetKeyAtIndex(unsigned aIndex
) {
93 MOZ_ASSERT(aIndex
< mSortedList
.Length());
94 return NS_ConvertASCIItoUTF16(mSortedList
[aIndex
].mName
);
96 const NS_ConvertASCIItoUTF16
GetValueAtIndex(unsigned aIndex
) {
98 MOZ_ASSERT(aIndex
< mSortedList
.Length());
99 return NS_ConvertASCIItoUTF16(mSortedList
[aIndex
].mValue
);
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;
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();
176 } // namespace mozilla
178 #endif // mozilla_dom_InternalHeaders_h