InternalRequest.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  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_InternalRequest_h
  6. #define mozilla_dom_InternalRequest_h
  7. #include "mozilla/dom/HeadersBinding.h"
  8. #include "mozilla/dom/InternalHeaders.h"
  9. #include "mozilla/dom/RequestBinding.h"
  10. #include "mozilla/LoadTainting.h"
  11. #include "mozilla/net/ReferrerPolicy.h"
  12. #include "nsIContentPolicy.h"
  13. #include "nsIInputStream.h"
  14. #include "nsISupportsImpl.h"
  15. #ifdef DEBUG
  16. #include "nsIURLParser.h"
  17. #include "nsNetCID.h"
  18. #include "nsServiceManagerUtils.h"
  19. #endif
  20. namespace mozilla {
  21. namespace ipc {
  22. class PrincipalInfo;
  23. } // namespace ipc
  24. namespace dom {
  25. /*
  26. * The mapping of RequestContext and nsContentPolicyType is currently as the
  27. * following. Note that this mapping is not perfect yet (see the TODO comments
  28. * below for examples).
  29. *
  30. * RequestContext | nsContentPolicyType
  31. * ------------------+--------------------
  32. * audio | TYPE_INTERNAL_AUDIO
  33. * beacon | TYPE_BEACON
  34. * cspreport | TYPE_CSP_REPORT
  35. * download |
  36. * embed | TYPE_INTERNAL_EMBED
  37. * eventsource |
  38. * favicon |
  39. * fetch | TYPE_FETCH
  40. * font | TYPE_FONT
  41. * form |
  42. * frame | TYPE_INTERNAL_FRAME
  43. * hyperlink |
  44. * iframe | TYPE_INTERNAL_IFRAME
  45. * image | TYPE_INTERNAL_IMAGE, TYPE_INTERNAL_IMAGE_PRELOAD, TYPE_INTERNAL_IMAGE_FAVICON
  46. * imageset | TYPE_IMAGESET
  47. * import | Not supported by Gecko
  48. * internal | TYPE_DOCUMENT, TYPE_XBL, TYPE_OTHER, TYPE_SAVEAS_DOWNLOAD
  49. * location |
  50. * manifest | TYPE_WEB_MANIFEST
  51. * object | TYPE_INTERNAL_OBJECT
  52. * ping | TYPE_PING
  53. * plugin | TYPE_OBJECT_SUBREQUEST
  54. * prefetch |
  55. * script | TYPE_INTERNAL_SCRIPT, TYPE_INTERNAL_SCRIPT_PRELOAD
  56. * sharedworker | TYPE_INTERNAL_SHARED_WORKER
  57. * subresource | Not supported by Gecko
  58. * style | TYPE_INTERNAL_STYLESHEET, TYPE_INTERNAL_STYLESHEET_PRELOAD
  59. * track | TYPE_INTERNAL_TRACK
  60. * video | TYPE_INTERNAL_VIDEO
  61. * worker | TYPE_INTERNAL_WORKER
  62. * xmlhttprequest | TYPE_INTERNAL_XMLHTTPREQUEST
  63. * eventsource | TYPE_INTERNAL_EVENTSOURCE
  64. * xslt | TYPE_XSLT
  65. *
  66. * TODO: Figure out if TYPE_REFRESH maps to anything useful
  67. * TODO: Figure out if TYPE_DTD maps to anything useful
  68. * TODO: Figure out if TYPE_WEBSOCKET maps to anything useful
  69. * TODO: Add a content type for prefetch
  70. * TODO: Use the content type for manifest when it becomes available
  71. * TODO: Add a content type for location
  72. * TODO: Add a content type for hyperlink
  73. * TODO: Add a content type for form
  74. * TODO: Add a content type for favicon
  75. * TODO: Add a content type for download
  76. */
  77. class Request;
  78. class IPCInternalRequest;
  79. #define kFETCH_CLIENT_REFERRER_STR "about:client"
  80. class InternalRequest final
  81. {
  82. friend class Request;
  83. public:
  84. NS_INLINE_DECL_THREADSAFE_REFCOUNTING(InternalRequest)
  85. InternalRequest(const nsACString& aURL, const nsACString& aFragment);
  86. InternalRequest(const nsACString& aURL,
  87. const nsACString& aFragment,
  88. const nsACString& aMethod,
  89. already_AddRefed<InternalHeaders> aHeaders,
  90. RequestCache aCacheMode,
  91. RequestMode aMode,
  92. RequestRedirect aRequestRedirect,
  93. RequestCredentials aRequestCredentials,
  94. const nsAString& aReferrer,
  95. ReferrerPolicy aReferrerPolicy,
  96. nsContentPolicyType aContentPolicyType,
  97. const nsAString& aIntegrity);
  98. explicit InternalRequest(const IPCInternalRequest& aIPCRequest);
  99. void ToIPC(IPCInternalRequest* aIPCRequest);
  100. already_AddRefed<InternalRequest> Clone();
  101. void
  102. GetMethod(nsCString& aMethod) const
  103. {
  104. aMethod.Assign(mMethod);
  105. }
  106. void
  107. SetMethod(const nsACString& aMethod)
  108. {
  109. mMethod.Assign(aMethod);
  110. }
  111. bool
  112. HasSimpleMethod() const
  113. {
  114. return mMethod.LowerCaseEqualsASCII("get") ||
  115. mMethod.LowerCaseEqualsASCII("post") ||
  116. mMethod.LowerCaseEqualsASCII("head");
  117. }
  118. // GetURL should get the request's current url with fragment. A request has
  119. // an associated current url. It is a pointer to the last fetch URL in
  120. // request's url list.
  121. void
  122. GetURL(nsACString& aURL) const
  123. {
  124. aURL.Assign(GetURLWithoutFragment());
  125. if (GetFragment().IsEmpty()) {
  126. return;
  127. }
  128. aURL.Append(NS_LITERAL_CSTRING("#"));
  129. aURL.Append(GetFragment());
  130. }
  131. const nsCString&
  132. GetURLWithoutFragment() const
  133. {
  134. MOZ_RELEASE_ASSERT(!mURLList.IsEmpty(),
  135. "Internal Request's urlList should not be empty.");
  136. return mURLList.LastElement();
  137. }
  138. // AddURL should append the url into url list.
  139. // Normally we strip the fragment from the URL in Request::Constructor and
  140. // pass the fragment as the second argument into it.
  141. // If a fragment is present in the URL it must be stripped and passed in
  142. // separately.
  143. void
  144. AddURL(const nsACString& aURL, const nsACString& aFragment)
  145. {
  146. MOZ_ASSERT(!aURL.IsEmpty());
  147. MOZ_ASSERT(!aURL.Contains('#'));
  148. mURLList.AppendElement(aURL);
  149. mFragment.Assign(aFragment);
  150. }
  151. // Get the URL list without their fragments.
  152. void
  153. GetURLListWithoutFragment(nsTArray<nsCString>& aURLList)
  154. {
  155. aURLList.Assign(mURLList);
  156. }
  157. void
  158. GetReferrer(nsAString& aReferrer) const
  159. {
  160. aReferrer.Assign(mReferrer);
  161. }
  162. void
  163. SetReferrer(const nsAString& aReferrer)
  164. {
  165. #ifdef DEBUG
  166. bool validReferrer = false;
  167. if (aReferrer.IsEmpty() ||
  168. aReferrer.EqualsLiteral(kFETCH_CLIENT_REFERRER_STR)) {
  169. validReferrer = true;
  170. } else {
  171. nsCOMPtr<nsIURLParser> parser = do_GetService(NS_STDURLPARSER_CONTRACTID);
  172. if (!parser) {
  173. NS_WARNING("Could not get parser to validate URL!");
  174. } else {
  175. uint32_t schemePos;
  176. int32_t schemeLen;
  177. uint32_t authorityPos;
  178. int32_t authorityLen;
  179. uint32_t pathPos;
  180. int32_t pathLen;
  181. NS_ConvertUTF16toUTF8 ref(aReferrer);
  182. nsresult rv = parser->ParseURL(ref.get(), ref.Length(),
  183. &schemePos, &schemeLen,
  184. &authorityPos, &authorityLen,
  185. &pathPos, &pathLen);
  186. if (NS_FAILED(rv)) {
  187. NS_WARNING("Invalid referrer URL!");
  188. } else if (schemeLen < 0 || authorityLen < 0) {
  189. NS_WARNING("Invalid referrer URL!");
  190. } else {
  191. validReferrer = true;
  192. }
  193. }
  194. }
  195. MOZ_ASSERT(validReferrer);
  196. #endif
  197. mReferrer.Assign(aReferrer);
  198. }
  199. ReferrerPolicy
  200. ReferrerPolicy_() const
  201. {
  202. return mReferrerPolicy;
  203. }
  204. void
  205. SetReferrerPolicy(ReferrerPolicy aReferrerPolicy)
  206. {
  207. mReferrerPolicy = aReferrerPolicy;
  208. }
  209. net::ReferrerPolicy
  210. GetEnvironmentReferrerPolicy() const
  211. {
  212. return mEnvironmentReferrerPolicy;
  213. }
  214. void
  215. SetEnvironmentReferrerPolicy(net::ReferrerPolicy aReferrerPolicy)
  216. {
  217. mEnvironmentReferrerPolicy = aReferrerPolicy;
  218. }
  219. bool
  220. SkipServiceWorker() const
  221. {
  222. return mSkipServiceWorker;
  223. }
  224. void
  225. SetSkipServiceWorker()
  226. {
  227. mSkipServiceWorker = true;
  228. }
  229. bool
  230. IsSynchronous() const
  231. {
  232. return mSynchronous;
  233. }
  234. RequestMode
  235. Mode() const
  236. {
  237. return mMode;
  238. }
  239. void
  240. SetMode(RequestMode aMode)
  241. {
  242. mMode = aMode;
  243. }
  244. RequestCredentials
  245. GetCredentialsMode() const
  246. {
  247. return mCredentialsMode;
  248. }
  249. void
  250. SetCredentialsMode(RequestCredentials aCredentialsMode)
  251. {
  252. mCredentialsMode = aCredentialsMode;
  253. }
  254. LoadTainting
  255. GetResponseTainting() const
  256. {
  257. return mResponseTainting;
  258. }
  259. void
  260. MaybeIncreaseResponseTainting(LoadTainting aTainting)
  261. {
  262. if (aTainting > mResponseTainting) {
  263. mResponseTainting = aTainting;
  264. }
  265. }
  266. RequestCache
  267. GetCacheMode() const
  268. {
  269. return mCacheMode;
  270. }
  271. void
  272. SetCacheMode(RequestCache aCacheMode)
  273. {
  274. mCacheMode = aCacheMode;
  275. }
  276. RequestRedirect
  277. GetRedirectMode() const
  278. {
  279. return mRedirectMode;
  280. }
  281. void
  282. SetRedirectMode(RequestRedirect aRedirectMode)
  283. {
  284. mRedirectMode = aRedirectMode;
  285. }
  286. const nsString&
  287. GetIntegrity() const
  288. {
  289. return mIntegrity;
  290. }
  291. void
  292. SetIntegrity(const nsAString& aIntegrity)
  293. {
  294. MOZ_ASSERT(mIntegrity.IsEmpty());
  295. mIntegrity.Assign(aIntegrity);
  296. }
  297. const nsCString&
  298. GetFragment() const
  299. {
  300. return mFragment;
  301. }
  302. nsContentPolicyType
  303. ContentPolicyType() const
  304. {
  305. return mContentPolicyType;
  306. }
  307. void
  308. SetContentPolicyType(nsContentPolicyType aContentPolicyType);
  309. void
  310. OverrideContentPolicyType(nsContentPolicyType aContentPolicyType);
  311. RequestContext
  312. Context() const
  313. {
  314. return MapContentPolicyTypeToRequestContext(mContentPolicyType);
  315. }
  316. bool
  317. UnsafeRequest() const
  318. {
  319. return mUnsafeRequest;
  320. }
  321. void
  322. SetUnsafeRequest()
  323. {
  324. mUnsafeRequest = true;
  325. }
  326. InternalHeaders*
  327. Headers()
  328. {
  329. return mHeaders;
  330. }
  331. bool
  332. ForceOriginHeader()
  333. {
  334. return mForceOriginHeader;
  335. }
  336. bool
  337. SameOriginDataURL() const
  338. {
  339. return mSameOriginDataURL;
  340. }
  341. void
  342. UnsetSameOriginDataURL()
  343. {
  344. mSameOriginDataURL = false;
  345. }
  346. void
  347. SetBody(nsIInputStream* aStream)
  348. {
  349. // A request's body may not be reset once set.
  350. MOZ_ASSERT_IF(aStream, !mBodyStream);
  351. mBodyStream = aStream;
  352. }
  353. // Will return the original stream!
  354. // Use a tee or copy if you don't want to erase the original.
  355. void
  356. GetBody(nsIInputStream** aStream)
  357. {
  358. nsCOMPtr<nsIInputStream> s = mBodyStream;
  359. s.forget(aStream);
  360. }
  361. // The global is used as the client for the new object.
  362. already_AddRefed<InternalRequest>
  363. GetRequestConstructorCopy(nsIGlobalObject* aGlobal, ErrorResult& aRv) const;
  364. bool
  365. WasCreatedByFetchEvent() const
  366. {
  367. return mCreatedByFetchEvent;
  368. }
  369. void
  370. SetCreatedByFetchEvent()
  371. {
  372. mCreatedByFetchEvent = true;
  373. }
  374. void
  375. ClearCreatedByFetchEvent()
  376. {
  377. mCreatedByFetchEvent = false;
  378. }
  379. bool
  380. IsNavigationRequest() const;
  381. bool
  382. IsWorkerRequest() const;
  383. bool
  384. IsClientRequest() const;
  385. void
  386. MaybeSkipCacheIfPerformingRevalidation();
  387. bool
  388. IsContentPolicyTypeOverridden() const
  389. {
  390. return mContentPolicyTypeOverridden;
  391. }
  392. static RequestMode
  393. MapChannelToRequestMode(nsIChannel* aChannel);
  394. static RequestCredentials
  395. MapChannelToRequestCredentials(nsIChannel* aChannel);
  396. // Takes ownership of the principal info.
  397. void
  398. SetPrincipalInfo(UniquePtr<mozilla::ipc::PrincipalInfo> aPrincipalInfo);
  399. const UniquePtr<mozilla::ipc::PrincipalInfo>&
  400. GetPrincipalInfo() const
  401. {
  402. return mPrincipalInfo;
  403. }
  404. private:
  405. // Does not copy mBodyStream. Use fallible Clone() for complete copy.
  406. explicit InternalRequest(const InternalRequest& aOther);
  407. ~InternalRequest();
  408. static RequestContext
  409. MapContentPolicyTypeToRequestContext(nsContentPolicyType aContentPolicyType);
  410. static bool
  411. IsNavigationContentPolicy(nsContentPolicyType aContentPolicyType);
  412. static bool
  413. IsWorkerContentPolicy(nsContentPolicyType aContentPolicyType);
  414. nsCString mMethod;
  415. // mURLList: a list of one or more fetch URLs
  416. nsTArray<nsCString> mURLList;
  417. RefPtr<InternalHeaders> mHeaders;
  418. nsCOMPtr<nsIInputStream> mBodyStream;
  419. nsContentPolicyType mContentPolicyType;
  420. // Empty string: no-referrer
  421. // "about:client": client (default)
  422. // URL: an URL
  423. nsString mReferrer;
  424. ReferrerPolicy mReferrerPolicy;
  425. // This will be used for request created from Window or Worker contexts
  426. // In case there's no Referrer Policy in Request, this will be passed to
  427. // channel.
  428. // The Environment Referrer Policy should be net::ReferrerPolicy so that it
  429. // could be associated with nsIHttpChannel.
  430. net::ReferrerPolicy mEnvironmentReferrerPolicy;
  431. RequestMode mMode;
  432. RequestCredentials mCredentialsMode;
  433. MOZ_INIT_OUTSIDE_CTOR LoadTainting mResponseTainting;
  434. RequestCache mCacheMode;
  435. RequestRedirect mRedirectMode;
  436. nsString mIntegrity;
  437. nsCString mFragment;
  438. MOZ_INIT_OUTSIDE_CTOR bool mAuthenticationFlag;
  439. MOZ_INIT_OUTSIDE_CTOR bool mForceOriginHeader;
  440. MOZ_INIT_OUTSIDE_CTOR bool mPreserveContentCodings;
  441. MOZ_INIT_OUTSIDE_CTOR bool mSameOriginDataURL;
  442. MOZ_INIT_OUTSIDE_CTOR bool mSkipServiceWorker;
  443. MOZ_INIT_OUTSIDE_CTOR bool mSynchronous;
  444. MOZ_INIT_OUTSIDE_CTOR bool mUnsafeRequest;
  445. MOZ_INIT_OUTSIDE_CTOR bool mUseURLCredentials;
  446. // This is only set when a Request object is created by a fetch event. We
  447. // use it to check if Service Workers are simply fetching intercepted Request
  448. // objects without modifying them.
  449. bool mCreatedByFetchEvent = false;
  450. // This is only set when Request.overrideContentPolicyType() has been set.
  451. // It is illegal to pass such a Request object to a fetch() method unless
  452. // if the caller has chrome privileges.
  453. bool mContentPolicyTypeOverridden = false;
  454. UniquePtr<mozilla::ipc::PrincipalInfo> mPrincipalInfo;
  455. };
  456. } // namespace dom
  457. } // namespace mozilla
  458. #endif // mozilla_dom_InternalRequest_h