InternalResponse.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  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_InternalResponse_h
  6. #define mozilla_dom_InternalResponse_h
  7. #include "nsIInputStream.h"
  8. #include "nsISupportsImpl.h"
  9. #include "mozilla/dom/ResponseBinding.h"
  10. #include "mozilla/dom/ChannelInfo.h"
  11. #include "mozilla/dom/InternalHeaders.h"
  12. #include "mozilla/UniquePtr.h"
  13. namespace mozilla {
  14. namespace ipc {
  15. class PrincipalInfo;
  16. class AutoIPCStream;
  17. } // namespace ipc
  18. namespace dom {
  19. class InternalHeaders;
  20. class IPCInternalResponse;
  21. class InternalResponse final
  22. {
  23. friend class FetchDriver;
  24. public:
  25. NS_INLINE_DECL_THREADSAFE_REFCOUNTING(InternalResponse)
  26. InternalResponse(uint16_t aStatus, const nsACString& aStatusText);
  27. static already_AddRefed<InternalResponse>
  28. FromIPC(const IPCInternalResponse& aIPCResponse);
  29. template<typename M>
  30. void
  31. ToIPC(IPCInternalResponse* aIPCResponse,
  32. M* aManager,
  33. UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoStream);
  34. already_AddRefed<InternalResponse> Clone();
  35. static already_AddRefed<InternalResponse>
  36. NetworkError()
  37. {
  38. RefPtr<InternalResponse> response = new InternalResponse(0, EmptyCString());
  39. ErrorResult result;
  40. response->Headers()->SetGuard(HeadersGuardEnum::Immutable, result);
  41. MOZ_ASSERT(!result.Failed());
  42. response->mType = ResponseType::Error;
  43. return response.forget();
  44. }
  45. already_AddRefed<InternalResponse>
  46. OpaqueResponse();
  47. already_AddRefed<InternalResponse>
  48. OpaqueRedirectResponse();
  49. already_AddRefed<InternalResponse>
  50. BasicResponse();
  51. already_AddRefed<InternalResponse>
  52. CORSResponse();
  53. ResponseType
  54. Type() const
  55. {
  56. MOZ_ASSERT_IF(mType == ResponseType::Error, !mWrappedResponse);
  57. MOZ_ASSERT_IF(mType == ResponseType::Default, !mWrappedResponse);
  58. MOZ_ASSERT_IF(mType == ResponseType::Basic, mWrappedResponse);
  59. MOZ_ASSERT_IF(mType == ResponseType::Cors, mWrappedResponse);
  60. MOZ_ASSERT_IF(mType == ResponseType::Opaque, mWrappedResponse);
  61. MOZ_ASSERT_IF(mType == ResponseType::Opaqueredirect, mWrappedResponse);
  62. return mType;
  63. }
  64. bool
  65. IsError() const
  66. {
  67. return Type() == ResponseType::Error;
  68. }
  69. // GetUrl should return last fetch URL in response's url list and null if
  70. // response's url list is the empty list.
  71. const nsCString&
  72. GetURL() const
  73. {
  74. // Empty urlList when response is a synthetic response.
  75. if (mURLList.IsEmpty()) {
  76. return EmptyCString();
  77. }
  78. return mURLList.LastElement();
  79. }
  80. void
  81. GetURLList(nsTArray<nsCString>& aURLList) const
  82. {
  83. aURLList.Assign(mURLList);
  84. }
  85. const nsCString&
  86. GetUnfilteredURL() const
  87. {
  88. if (mWrappedResponse) {
  89. return mWrappedResponse->GetURL();
  90. }
  91. return GetURL();
  92. }
  93. void
  94. GetUnfilteredURLList(nsTArray<nsCString>& aURLList) const
  95. {
  96. if (mWrappedResponse) {
  97. return mWrappedResponse->GetURLList(aURLList);
  98. }
  99. return GetURLList(aURLList);
  100. }
  101. void
  102. SetURLList(const nsTArray<nsCString>& aURLList)
  103. {
  104. mURLList.Assign(aURLList);
  105. #ifdef DEBUG
  106. for(uint32_t i = 0; i < mURLList.Length(); ++i) {
  107. MOZ_ASSERT(mURLList[i].Find(NS_LITERAL_CSTRING("#")) == kNotFound);
  108. }
  109. #endif
  110. }
  111. uint16_t
  112. GetStatus() const
  113. {
  114. return mStatus;
  115. }
  116. uint16_t
  117. GetUnfilteredStatus() const
  118. {
  119. if (mWrappedResponse) {
  120. return mWrappedResponse->GetStatus();
  121. }
  122. return GetStatus();
  123. }
  124. const nsCString&
  125. GetStatusText() const
  126. {
  127. return mStatusText;
  128. }
  129. const nsCString&
  130. GetUnfilteredStatusText() const
  131. {
  132. if (mWrappedResponse) {
  133. return mWrappedResponse->GetStatusText();
  134. }
  135. return GetStatusText();
  136. }
  137. InternalHeaders*
  138. Headers()
  139. {
  140. return mHeaders;
  141. }
  142. InternalHeaders*
  143. UnfilteredHeaders()
  144. {
  145. if (mWrappedResponse) {
  146. return mWrappedResponse->Headers();
  147. };
  148. return Headers();
  149. }
  150. void
  151. GetUnfilteredBody(nsIInputStream** aStream, int64_t* aBodySize = nullptr)
  152. {
  153. if (mWrappedResponse) {
  154. MOZ_ASSERT(!mBody);
  155. return mWrappedResponse->GetBody(aStream, aBodySize);
  156. }
  157. nsCOMPtr<nsIInputStream> stream = mBody;
  158. stream.forget(aStream);
  159. if (aBodySize) {
  160. *aBodySize = mBodySize;
  161. }
  162. }
  163. void
  164. GetBody(nsIInputStream** aStream, int64_t* aBodySize = nullptr)
  165. {
  166. if (Type() == ResponseType::Opaque ||
  167. Type() == ResponseType::Opaqueredirect) {
  168. *aStream = nullptr;
  169. if (aBodySize) {
  170. *aBodySize = UNKNOWN_BODY_SIZE;
  171. }
  172. return;
  173. }
  174. return GetUnfilteredBody(aStream, aBodySize);
  175. }
  176. void
  177. SetBody(nsIInputStream* aBody, int64_t aBodySize)
  178. {
  179. if (mWrappedResponse) {
  180. return mWrappedResponse->SetBody(aBody, aBodySize);
  181. }
  182. // A request's body may not be reset once set.
  183. MOZ_ASSERT(!mBody);
  184. MOZ_ASSERT(mBodySize == UNKNOWN_BODY_SIZE);
  185. // Check arguments.
  186. MOZ_ASSERT(aBodySize == UNKNOWN_BODY_SIZE || aBodySize >= 0);
  187. // If body is not given, then size must be unknown.
  188. MOZ_ASSERT_IF(!aBody, aBodySize == UNKNOWN_BODY_SIZE);
  189. mBody = aBody;
  190. mBodySize = aBodySize;
  191. }
  192. void
  193. InitChannelInfo(nsIChannel* aChannel)
  194. {
  195. mChannelInfo.InitFromChannel(aChannel);
  196. }
  197. void
  198. InitChannelInfo(const mozilla::ipc::IPCChannelInfo& aChannelInfo)
  199. {
  200. mChannelInfo.InitFromIPCChannelInfo(aChannelInfo);
  201. }
  202. void
  203. InitChannelInfo(const ChannelInfo& aChannelInfo)
  204. {
  205. mChannelInfo = aChannelInfo;
  206. }
  207. const ChannelInfo&
  208. GetChannelInfo() const
  209. {
  210. return mChannelInfo;
  211. }
  212. const UniquePtr<mozilla::ipc::PrincipalInfo>&
  213. GetPrincipalInfo() const
  214. {
  215. return mPrincipalInfo;
  216. }
  217. bool
  218. IsRedirected() const
  219. {
  220. return mURLList.Length() > 1;
  221. }
  222. // Takes ownership of the principal info.
  223. void
  224. SetPrincipalInfo(UniquePtr<mozilla::ipc::PrincipalInfo> aPrincipalInfo);
  225. LoadTainting
  226. GetTainting() const;
  227. already_AddRefed<InternalResponse>
  228. Unfiltered();
  229. private:
  230. ~InternalResponse();
  231. explicit InternalResponse(const InternalResponse& aOther) = delete;
  232. InternalResponse& operator=(const InternalResponse&) = delete;
  233. // Returns an instance of InternalResponse which is a copy of this
  234. // InternalResponse, except headers, body and wrapped response (if any) which
  235. // are left uninitialized. Used for cloning and filtering.
  236. already_AddRefed<InternalResponse> CreateIncompleteCopy();
  237. ResponseType mType;
  238. nsCString mTerminationReason;
  239. // A response has an associated url list (a list of zero or more fetch URLs).
  240. // Unless stated otherwise, it is the empty list. The current url is the last
  241. // element in mURLlist
  242. nsTArray<nsCString> mURLList;
  243. const uint16_t mStatus;
  244. const nsCString mStatusText;
  245. RefPtr<InternalHeaders> mHeaders;
  246. nsCOMPtr<nsIInputStream> mBody;
  247. int64_t mBodySize;
  248. public:
  249. static const int64_t UNKNOWN_BODY_SIZE = -1;
  250. private:
  251. ChannelInfo mChannelInfo;
  252. UniquePtr<mozilla::ipc::PrincipalInfo> mPrincipalInfo;
  253. // For filtered responses.
  254. // Cache, and SW interception should always serialize/access the underlying
  255. // unfiltered headers and when deserializing, create an InternalResponse
  256. // with the unfiltered headers followed by wrapping it.
  257. RefPtr<InternalResponse> mWrappedResponse;
  258. };
  259. } // namespace dom
  260. } // namespace mozilla
  261. #endif // mozilla_dom_InternalResponse_h