InternalHeaders.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #ifndef mozilla_dom_InternalHeaders_h
  6. #define mozilla_dom_InternalHeaders_h
  7. // needed for HeadersGuardEnum.
  8. #include "mozilla/dom/HeadersBinding.h"
  9. #include "mozilla/dom/UnionTypes.h"
  10. #include "nsClassHashtable.h"
  11. #include "nsWrapperCache.h"
  12. namespace mozilla {
  13. class ErrorResult;
  14. namespace dom {
  15. template<typename K, typename V> class Record;
  16. class HeadersEntry;
  17. class InternalHeaders final
  18. {
  19. NS_INLINE_DECL_THREADSAFE_REFCOUNTING(InternalHeaders)
  20. public:
  21. struct Entry
  22. {
  23. Entry(const nsACString& aName, const nsACString& aValue)
  24. : mName(aName)
  25. , mValue(aValue)
  26. { }
  27. Entry() { }
  28. nsCString mName;
  29. nsCString mValue;
  30. };
  31. private:
  32. HeadersGuardEnum mGuard;
  33. nsTArray<Entry> mList;
  34. nsTArray<Entry> mSortedList;
  35. // This boolean is set to true at any writing operation to mList. It's set to
  36. // false when mSortedList is regenerated. This happens when the header is
  37. // iterated.
  38. bool mListDirty;
  39. public:
  40. explicit InternalHeaders(HeadersGuardEnum aGuard = HeadersGuardEnum::None)
  41. : mGuard(aGuard)
  42. , mListDirty(false)
  43. {
  44. }
  45. explicit InternalHeaders(const InternalHeaders& aOther)
  46. : mGuard(HeadersGuardEnum::None)
  47. , mListDirty(true)
  48. {
  49. ErrorResult result;
  50. Fill(aOther, result);
  51. MOZ_ASSERT(!result.Failed());
  52. // Note that it's important to set the guard after Fill(), to make sure
  53. // that Fill() doesn't fail if aOther is immutable.
  54. mGuard = aOther.mGuard;
  55. }
  56. explicit InternalHeaders(const nsTArray<Entry>&& aHeaders,
  57. HeadersGuardEnum aGuard = HeadersGuardEnum::None);
  58. InternalHeaders(const nsTArray<HeadersEntry>& aHeadersEntryList,
  59. HeadersGuardEnum aGuard);
  60. void ToIPC(nsTArray<HeadersEntry>& aIPCHeaders,
  61. HeadersGuardEnum& aGuard);
  62. void Append(const nsACString& aName, const nsACString& aValue,
  63. ErrorResult& aRv);
  64. void Delete(const nsACString& aName, ErrorResult& aRv);
  65. void Get(const nsACString& aName, nsACString& aValue, ErrorResult& aRv) const;
  66. void GetFirst(const nsACString& aName, nsACString& aValue, ErrorResult& aRv) const;
  67. bool Has(const nsACString& aName, ErrorResult& aRv) const;
  68. void Set(const nsACString& aName, const nsACString& aValue, ErrorResult& aRv);
  69. uint32_t GetIterableLength()
  70. {
  71. MaybeSortList();
  72. return mSortedList.Length();
  73. }
  74. const NS_ConvertASCIItoUTF16 GetKeyAtIndex(unsigned aIndex)
  75. {
  76. MaybeSortList();
  77. MOZ_ASSERT(aIndex < mSortedList.Length());
  78. return NS_ConvertASCIItoUTF16(mSortedList[aIndex].mName);
  79. }
  80. const NS_ConvertASCIItoUTF16 GetValueAtIndex(unsigned aIndex)
  81. {
  82. MaybeSortList();
  83. MOZ_ASSERT(aIndex < mSortedList.Length());
  84. return NS_ConvertASCIItoUTF16(mSortedList[aIndex].mValue);
  85. }
  86. void Clear();
  87. HeadersGuardEnum Guard() const { return mGuard; }
  88. void SetGuard(HeadersGuardEnum aGuard, ErrorResult& aRv);
  89. void Fill(const InternalHeaders& aInit, ErrorResult& aRv);
  90. void Fill(const Sequence<Sequence<nsCString>>& aInit, ErrorResult& aRv);
  91. void Fill(const Record<nsCString, nsCString>& aInit, ErrorResult& aRv);
  92. bool HasOnlySimpleHeaders() const;
  93. bool HasRevalidationHeaders() const;
  94. static already_AddRefed<InternalHeaders>
  95. BasicHeaders(InternalHeaders* aHeaders);
  96. static already_AddRefed<InternalHeaders>
  97. CORSHeaders(InternalHeaders* aHeaders);
  98. void
  99. GetEntries(nsTArray<InternalHeaders::Entry>& aEntries) const;
  100. void
  101. GetUnsafeHeaders(nsTArray<nsCString>& aNames) const;
  102. private:
  103. virtual ~InternalHeaders();
  104. static bool IsInvalidName(const nsACString& aName, ErrorResult& aRv);
  105. static bool IsInvalidValue(const nsACString& aValue, ErrorResult& aRv);
  106. bool IsImmutable(ErrorResult& aRv) const;
  107. bool IsForbiddenRequestHeader(const nsACString& aName) const;
  108. bool IsForbiddenRequestNoCorsHeader(const nsACString& aName) const;
  109. bool IsForbiddenRequestNoCorsHeader(const nsACString& aName,
  110. const nsACString& aValue) const;
  111. bool IsForbiddenResponseHeader(const nsACString& aName) const;
  112. bool IsInvalidMutableHeader(const nsACString& aName,
  113. ErrorResult& aRv) const
  114. {
  115. return IsInvalidMutableHeader(aName, EmptyCString(), aRv);
  116. }
  117. bool IsInvalidMutableHeader(const nsACString& aName,
  118. const nsACString& aValue,
  119. ErrorResult& aRv) const
  120. {
  121. return IsInvalidName(aName, aRv) ||
  122. IsInvalidValue(aValue, aRv) ||
  123. IsImmutable(aRv) ||
  124. IsForbiddenRequestHeader(aName) ||
  125. IsForbiddenRequestNoCorsHeader(aName, aValue) ||
  126. IsForbiddenResponseHeader(aName);
  127. }
  128. static bool IsSimpleHeader(const nsACString& aName,
  129. const nsACString& aValue);
  130. static bool IsRevalidationHeader(const nsACString& aName);
  131. void MaybeSortList();
  132. void SetListDirty();
  133. };
  134. } // namespace dom
  135. } // namespace mozilla
  136. #endif // mozilla_dom_InternalHeaders_h