HttpChannelParent.cpp 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833
  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. // HttpLog.h should generally be included first
  6. #include "HttpLog.h"
  7. #include "mozilla/ipc/FileDescriptorSetParent.h"
  8. #include "mozilla/net/HttpChannelParent.h"
  9. #include "mozilla/dom/Element.h"
  10. #include "mozilla/dom/TabParent.h"
  11. #include "mozilla/net/NeckoParent.h"
  12. #include "mozilla/UniquePtr.h"
  13. #include "mozilla/Unused.h"
  14. #include "HttpChannelParentListener.h"
  15. #include "nsHttpHandler.h"
  16. #include "nsNetUtil.h"
  17. #include "nsISupportsPriority.h"
  18. #include "nsIAuthPromptProvider.h"
  19. #include "nsSerializationHelper.h"
  20. #include "nsISerializable.h"
  21. #include "nsIAssociatedContentSecurity.h"
  22. #include "nsIApplicationCacheService.h"
  23. #include "mozilla/ipc/InputStreamUtils.h"
  24. #include "mozilla/ipc/IPCStreamUtils.h"
  25. #include "mozilla/ipc/URIUtils.h"
  26. #include "SerializedLoadContext.h"
  27. #include "nsIAuthInformation.h"
  28. #include "nsIAuthPromptCallback.h"
  29. #include "nsIContentPolicy.h"
  30. #include "mozilla/ipc/BackgroundUtils.h"
  31. #include "nsICachingChannel.h"
  32. #include "mozilla/LoadInfo.h"
  33. #include "nsQueryObject.h"
  34. #include "mozilla/BasePrincipal.h"
  35. #include "nsCORSListenerProxy.h"
  36. #include "nsIIPCSerializableInputStream.h"
  37. #include "nsIPrompt.h"
  38. #include "nsIWindowWatcher.h"
  39. #include "nsIDocument.h"
  40. #include "nsStringStream.h"
  41. #include "nsIStorageStream.h"
  42. #include "nsStreamUtils.h"
  43. using mozilla::BasePrincipal;
  44. using namespace mozilla::dom;
  45. using namespace mozilla::ipc;
  46. namespace mozilla {
  47. namespace net {
  48. HttpChannelParent::HttpChannelParent(const PBrowserOrId& iframeEmbedding,
  49. nsILoadContext* aLoadContext,
  50. PBOverrideStatus aOverrideStatus)
  51. : mIPCClosed(false)
  52. , mStoredStatus(NS_OK)
  53. , mStoredProgress(0)
  54. , mStoredProgressMax(0)
  55. , mSentRedirect1Begin(false)
  56. , mSentRedirect1BeginFailed(false)
  57. , mReceivedRedirect2Verify(false)
  58. , mPBOverride(aOverrideStatus)
  59. , mLoadContext(aLoadContext)
  60. , mStatus(NS_OK)
  61. , mPendingDiversion(false)
  62. , mDivertingFromChild(false)
  63. , mDivertedOnStartRequest(false)
  64. , mSuspendedForDiversion(false)
  65. , mSuspendAfterSynthesizeResponse(false)
  66. , mWillSynthesizeResponse(false)
  67. , mNestedFrameId(0)
  68. {
  69. LOG(("Creating HttpChannelParent [this=%p]\n", this));
  70. // Ensure gHttpHandler is initialized: we need the atom table up and running.
  71. nsCOMPtr<nsIHttpProtocolHandler> dummyInitializer =
  72. do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http");
  73. MOZ_ASSERT(gHttpHandler);
  74. mHttpHandler = gHttpHandler;
  75. if (iframeEmbedding.type() == PBrowserOrId::TPBrowserParent) {
  76. mTabParent = static_cast<dom::TabParent*>(iframeEmbedding.get_PBrowserParent());
  77. } else {
  78. mNestedFrameId = iframeEmbedding.get_TabId();
  79. }
  80. mEventQ = new ChannelEventQueue(static_cast<nsIParentRedirectingChannel*>(this));
  81. }
  82. HttpChannelParent::~HttpChannelParent()
  83. {
  84. LOG(("Destroying HttpChannelParent [this=%p]\n", this));
  85. }
  86. void
  87. HttpChannelParent::ActorDestroy(ActorDestroyReason why)
  88. {
  89. // We may still have refcount>0 if nsHttpChannel hasn't called OnStopRequest
  90. // yet, but child process has crashed. We must not try to send any more msgs
  91. // to child, or IPDL will kill chrome process, too.
  92. mIPCClosed = true;
  93. // If this is an intercepted channel, we need to make sure that any resources are
  94. // cleaned up to avoid leaks.
  95. if (mParentListener) {
  96. mParentListener->ClearInterceptedChannel();
  97. }
  98. }
  99. bool
  100. HttpChannelParent::Init(const HttpChannelCreationArgs& aArgs)
  101. {
  102. LOG(("HttpChannelParent::Init [this=%p]\n", this));
  103. switch (aArgs.type()) {
  104. case HttpChannelCreationArgs::THttpChannelOpenArgs:
  105. {
  106. const HttpChannelOpenArgs& a = aArgs.get_HttpChannelOpenArgs();
  107. return DoAsyncOpen(a.uri(), a.original(), a.doc(), a.referrer(),
  108. a.referrerPolicy(), a.apiRedirectTo(), a.topWindowURI(),
  109. a.loadFlags(), a.requestHeaders(),
  110. a.requestMethod(), a.uploadStream(),
  111. a.uploadStreamHasHeaders(), a.priority(), a.classOfService(),
  112. a.redirectionLimit(), a.allowPipelining(), a.allowSTS(),
  113. a.thirdPartyFlags(), a.resumeAt(), a.startPos(),
  114. a.entityID(), a.chooseApplicationCache(),
  115. a.appCacheClientID(), a.allowSpdy(), a.allowAltSvc(), a.beConservative(),
  116. a.loadInfo(), a.synthesizedResponseHead(),
  117. a.synthesizedSecurityInfoSerialization(),
  118. a.cacheKey(), a.requestContextID(), a.preflightArgs(),
  119. a.initialRwin(), a.blockAuthPrompt(),
  120. a.suspendAfterSynthesizeResponse(),
  121. a.allowStaleCacheContent(), a.contentTypeHint(),
  122. a.channelId(), a.contentWindowId(), a.preferredAlternativeType(),
  123. a.launchServiceWorkerStart(),
  124. a.launchServiceWorkerEnd(),
  125. a.dispatchFetchEventStart(),
  126. a.dispatchFetchEventEnd(),
  127. a.handleFetchEventStart(),
  128. a.handleFetchEventEnd());
  129. }
  130. case HttpChannelCreationArgs::THttpChannelConnectArgs:
  131. {
  132. const HttpChannelConnectArgs& cArgs = aArgs.get_HttpChannelConnectArgs();
  133. return ConnectChannel(cArgs.registrarId(), cArgs.shouldIntercept());
  134. }
  135. default:
  136. NS_NOTREACHED("unknown open type");
  137. return false;
  138. }
  139. }
  140. //-----------------------------------------------------------------------------
  141. // HttpChannelParent::nsISupports
  142. //-----------------------------------------------------------------------------
  143. NS_IMPL_ADDREF(HttpChannelParent)
  144. NS_IMPL_RELEASE(HttpChannelParent)
  145. NS_INTERFACE_MAP_BEGIN(HttpChannelParent)
  146. NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
  147. NS_INTERFACE_MAP_ENTRY(nsIProgressEventSink)
  148. NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
  149. NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
  150. NS_INTERFACE_MAP_ENTRY(nsIParentChannel)
  151. NS_INTERFACE_MAP_ENTRY(nsIAuthPromptProvider)
  152. NS_INTERFACE_MAP_ENTRY(nsIParentRedirectingChannel)
  153. NS_INTERFACE_MAP_ENTRY(nsIDeprecationWarner)
  154. NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIParentRedirectingChannel)
  155. if (aIID.Equals(NS_GET_IID(HttpChannelParent))) {
  156. foundInterface = static_cast<nsIInterfaceRequestor*>(this);
  157. } else
  158. NS_INTERFACE_MAP_END
  159. //-----------------------------------------------------------------------------
  160. // HttpChannelParent::nsIInterfaceRequestor
  161. //-----------------------------------------------------------------------------
  162. NS_IMETHODIMP
  163. HttpChannelParent::GetInterface(const nsIID& aIID, void **result)
  164. {
  165. if (aIID.Equals(NS_GET_IID(nsIAuthPromptProvider)) ||
  166. aIID.Equals(NS_GET_IID(nsISecureBrowserUI))) {
  167. if (mTabParent) {
  168. return mTabParent->QueryInterface(aIID, result);
  169. }
  170. }
  171. // Only support nsIAuthPromptProvider in Content process
  172. if (XRE_IsParentProcess() &&
  173. aIID.Equals(NS_GET_IID(nsIAuthPromptProvider))) {
  174. *result = nullptr;
  175. return NS_OK;
  176. }
  177. // Only support nsILoadContext if child channel's callbacks did too
  178. if (aIID.Equals(NS_GET_IID(nsILoadContext)) && mLoadContext) {
  179. nsCOMPtr<nsILoadContext> copy = mLoadContext;
  180. copy.forget(result);
  181. return NS_OK;
  182. }
  183. if (mTabParent && aIID.Equals(NS_GET_IID(nsIPrompt))) {
  184. nsCOMPtr<Element> frameElement = mTabParent->GetOwnerElement();
  185. if (frameElement) {
  186. nsCOMPtr<nsPIDOMWindowOuter> win =frameElement->OwnerDoc()->GetWindow();
  187. NS_ENSURE_TRUE(win, NS_ERROR_UNEXPECTED);
  188. nsresult rv;
  189. nsCOMPtr<nsIWindowWatcher> wwatch =
  190. do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
  191. if (NS_WARN_IF(!NS_SUCCEEDED(rv))) {
  192. return rv;
  193. }
  194. nsCOMPtr<nsIPrompt> prompt;
  195. rv = wwatch->GetNewPrompter(win, getter_AddRefs(prompt));
  196. if (NS_WARN_IF(!NS_SUCCEEDED(rv))) {
  197. return rv;
  198. }
  199. prompt.forget(result);
  200. return NS_OK;
  201. }
  202. }
  203. return QueryInterface(aIID, result);
  204. }
  205. //-----------------------------------------------------------------------------
  206. // HttpChannelParent::PHttpChannelParent
  207. //-----------------------------------------------------------------------------
  208. void
  209. HttpChannelParent::InvokeAsyncOpen(nsresult rv)
  210. {
  211. if (NS_FAILED(rv)) {
  212. Unused << SendFailedAsyncOpen(rv);
  213. return;
  214. }
  215. nsCOMPtr<nsILoadInfo> loadInfo;
  216. rv = mChannel->GetLoadInfo(getter_AddRefs(loadInfo));
  217. if (NS_FAILED(rv)) {
  218. Unused << SendFailedAsyncOpen(rv);
  219. return;
  220. }
  221. if (loadInfo && loadInfo->GetEnforceSecurity()) {
  222. rv = mChannel->AsyncOpen2(mParentListener);
  223. }
  224. else {
  225. rv = mChannel->AsyncOpen(mParentListener, nullptr);
  226. }
  227. if (NS_FAILED(rv)) {
  228. Unused << SendFailedAsyncOpen(rv);
  229. }
  230. }
  231. namespace {
  232. class InvokeAsyncOpen : public Runnable
  233. {
  234. nsMainThreadPtrHandle<nsIInterfaceRequestor> mChannel;
  235. nsresult mStatus;
  236. public:
  237. InvokeAsyncOpen(const nsMainThreadPtrHandle<nsIInterfaceRequestor>& aChannel,
  238. nsresult aStatus)
  239. : mChannel(aChannel)
  240. , mStatus(aStatus)
  241. {
  242. }
  243. NS_IMETHOD Run()
  244. {
  245. RefPtr<HttpChannelParent> channel = do_QueryObject(mChannel.get());
  246. channel->InvokeAsyncOpen(mStatus);
  247. return NS_OK;
  248. }
  249. };
  250. struct UploadStreamClosure {
  251. nsMainThreadPtrHandle<nsIInterfaceRequestor> mChannel;
  252. explicit UploadStreamClosure(const nsMainThreadPtrHandle<nsIInterfaceRequestor>& aChannel)
  253. : mChannel(aChannel)
  254. {
  255. }
  256. };
  257. void
  258. UploadCopyComplete(void* aClosure, nsresult aStatus) {
  259. // Called on the Stream Transport Service thread by NS_AsyncCopy
  260. MOZ_ASSERT(!NS_IsMainThread());
  261. UniquePtr<UploadStreamClosure> closure(static_cast<UploadStreamClosure*>(aClosure));
  262. nsCOMPtr<nsIRunnable> event = new InvokeAsyncOpen(closure->mChannel, aStatus);
  263. NS_DispatchToMainThread(event);
  264. }
  265. } // anonymous namespace
  266. bool
  267. HttpChannelParent::DoAsyncOpen( const URIParams& aURI,
  268. const OptionalURIParams& aOriginalURI,
  269. const OptionalURIParams& aDocURI,
  270. const OptionalURIParams& aReferrerURI,
  271. const uint32_t& aReferrerPolicy,
  272. const OptionalURIParams& aAPIRedirectToURI,
  273. const OptionalURIParams& aTopWindowURI,
  274. const uint32_t& aLoadFlags,
  275. const RequestHeaderTuples& requestHeaders,
  276. const nsCString& requestMethod,
  277. const OptionalIPCStream& uploadStream,
  278. const bool& uploadStreamHasHeaders,
  279. const uint16_t& priority,
  280. const uint32_t& classOfService,
  281. const uint8_t& redirectionLimit,
  282. const bool& allowPipelining,
  283. const bool& allowSTS,
  284. const uint32_t& thirdPartyFlags,
  285. const bool& doResumeAt,
  286. const uint64_t& startPos,
  287. const nsCString& entityID,
  288. const bool& chooseApplicationCache,
  289. const nsCString& appCacheClientID,
  290. const bool& allowSpdy,
  291. const bool& allowAltSvc,
  292. const bool& beConservative,
  293. const OptionalLoadInfoArgs& aLoadInfoArgs,
  294. const OptionalHttpResponseHead& aSynthesizedResponseHead,
  295. const nsCString& aSecurityInfoSerialization,
  296. const uint32_t& aCacheKey,
  297. const nsCString& aRequestContextID,
  298. const OptionalCorsPreflightArgs& aCorsPreflightArgs,
  299. const uint32_t& aInitialRwin,
  300. const bool& aBlockAuthPrompt,
  301. const bool& aSuspendAfterSynthesizeResponse,
  302. const bool& aAllowStaleCacheContent,
  303. const nsCString& aContentTypeHint,
  304. const nsCString& aChannelId,
  305. const uint64_t& aContentWindowId,
  306. const nsCString& aPreferredAlternativeType,
  307. const TimeStamp& aLaunchServiceWorkerStart,
  308. const TimeStamp& aLaunchServiceWorkerEnd,
  309. const TimeStamp& aDispatchFetchEventStart,
  310. const TimeStamp& aDispatchFetchEventEnd,
  311. const TimeStamp& aHandleFetchEventStart,
  312. const TimeStamp& aHandleFetchEventEnd)
  313. {
  314. nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
  315. if (!uri) {
  316. // URIParams does MOZ_ASSERT if null, but we need to protect opt builds from
  317. // null deref here.
  318. return false;
  319. }
  320. nsCOMPtr<nsIURI> originalUri = DeserializeURI(aOriginalURI);
  321. nsCOMPtr<nsIURI> docUri = DeserializeURI(aDocURI);
  322. nsCOMPtr<nsIURI> referrerUri = DeserializeURI(aReferrerURI);
  323. nsCOMPtr<nsIURI> apiRedirectToUri = DeserializeURI(aAPIRedirectToURI);
  324. nsCOMPtr<nsIURI> topWindowUri = DeserializeURI(aTopWindowURI);
  325. LOG(("HttpChannelParent RecvAsyncOpen [this=%p uri=%s]\n",
  326. this, uri->GetSpecOrDefault().get()));
  327. nsresult rv;
  328. nsCOMPtr<nsIIOService> ios(do_GetIOService(&rv));
  329. if (NS_FAILED(rv))
  330. return SendFailedAsyncOpen(rv);
  331. nsCOMPtr<nsILoadInfo> loadInfo;
  332. rv = mozilla::ipc::LoadInfoArgsToLoadInfo(aLoadInfoArgs,
  333. getter_AddRefs(loadInfo));
  334. if (NS_FAILED(rv)) {
  335. return SendFailedAsyncOpen(rv);
  336. }
  337. NeckoOriginAttributes attrs;
  338. rv = loadInfo->GetOriginAttributes(&attrs);
  339. if (NS_FAILED(rv)) {
  340. return SendFailedAsyncOpen(rv);
  341. }
  342. nsCOMPtr<nsIChannel> channel;
  343. rv = NS_NewChannelInternal(getter_AddRefs(channel), uri, loadInfo,
  344. nullptr, nullptr, aLoadFlags, ios);
  345. if (NS_FAILED(rv))
  346. return SendFailedAsyncOpen(rv);
  347. // This cast is safe since this is AsyncOpen specific to http. channel
  348. // is ensured to be nsHttpChannel.
  349. mChannel = static_cast<nsHttpChannel *>(channel.get());
  350. // Set the channelId allocated in child to the parent instance
  351. mChannel->SetChannelId(aChannelId);
  352. mChannel->SetTopLevelContentWindowId(aContentWindowId);
  353. mChannel->SetWarningReporter(this);
  354. mChannel->SetTimingEnabled(true);
  355. if (mPBOverride != kPBOverride_Unset) {
  356. mChannel->SetPrivate(mPBOverride == kPBOverride_Private ? true : false);
  357. }
  358. if (doResumeAt)
  359. mChannel->ResumeAt(startPos, entityID);
  360. if (originalUri)
  361. mChannel->SetOriginalURI(originalUri);
  362. if (docUri)
  363. mChannel->SetDocumentURI(docUri);
  364. if (referrerUri)
  365. mChannel->SetReferrerWithPolicyInternal(referrerUri, aReferrerPolicy);
  366. if (apiRedirectToUri)
  367. mChannel->RedirectTo(apiRedirectToUri);
  368. if (topWindowUri)
  369. mChannel->SetTopWindowURI(topWindowUri);
  370. if (aLoadFlags != nsIRequest::LOAD_NORMAL)
  371. mChannel->SetLoadFlags(aLoadFlags);
  372. for (uint32_t i = 0; i < requestHeaders.Length(); i++) {
  373. if (requestHeaders[i].mEmpty) {
  374. mChannel->SetEmptyRequestHeader(requestHeaders[i].mHeader);
  375. } else {
  376. mChannel->SetRequestHeader(requestHeaders[i].mHeader,
  377. requestHeaders[i].mValue,
  378. requestHeaders[i].mMerge);
  379. }
  380. }
  381. mParentListener = new HttpChannelParentListener(this);
  382. mChannel->SetNotificationCallbacks(mParentListener);
  383. mChannel->SetRequestMethod(nsDependentCString(requestMethod.get()));
  384. if (aCorsPreflightArgs.type() == OptionalCorsPreflightArgs::TCorsPreflightArgs) {
  385. const CorsPreflightArgs& args = aCorsPreflightArgs.get_CorsPreflightArgs();
  386. mChannel->SetCorsPreflightParameters(args.unsafeHeaders());
  387. }
  388. bool delayAsyncOpen = false;
  389. nsCOMPtr<nsIInputStream> stream = DeserializeIPCStream(uploadStream);
  390. if (stream) {
  391. // FIXME: The fast path of using the existing stream currently only applies to streams
  392. // that have had their entire contents serialized from the child at this point.
  393. // Once bug 1294446 and bug 1294450 are fixed it is worth revisiting this heuristic.
  394. nsCOMPtr<nsIIPCSerializableInputStream> completeStream = do_QueryInterface(stream);
  395. if (!completeStream) {
  396. delayAsyncOpen = true;
  397. // buffer size matches PSendStream transfer size.
  398. const uint32_t kBufferSize = 32768;
  399. nsCOMPtr<nsIStorageStream> storageStream;
  400. nsresult rv = NS_NewStorageStream(kBufferSize, UINT32_MAX,
  401. getter_AddRefs(storageStream));
  402. if (NS_WARN_IF(NS_FAILED(rv))) {
  403. return SendFailedAsyncOpen(rv);
  404. }
  405. nsCOMPtr<nsIInputStream> newUploadStream;
  406. rv = storageStream->NewInputStream(0, getter_AddRefs(newUploadStream));
  407. if (NS_WARN_IF(NS_FAILED(rv))) {
  408. return SendFailedAsyncOpen(rv);
  409. }
  410. nsCOMPtr<nsIOutputStream> sink;
  411. rv = storageStream->GetOutputStream(0, getter_AddRefs(sink));
  412. if (NS_WARN_IF(NS_FAILED(rv))) {
  413. return SendFailedAsyncOpen(rv);
  414. }
  415. nsCOMPtr<nsIEventTarget> target =
  416. do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv);
  417. if (NS_FAILED(rv) || !target) {
  418. return SendFailedAsyncOpen(rv);
  419. }
  420. nsCOMPtr<nsIInterfaceRequestor> iir = static_cast<nsIInterfaceRequestor*>(this);
  421. nsMainThreadPtrHandle<nsIInterfaceRequestor> handle =
  422. nsMainThreadPtrHandle<nsIInterfaceRequestor>(
  423. new nsMainThreadPtrHolder<nsIInterfaceRequestor>(iir));
  424. UniquePtr<UploadStreamClosure> closure(new UploadStreamClosure(handle));
  425. // Accumulate the stream contents as the child sends it. We will continue with
  426. // the AsyncOpen process once the full stream has been received.
  427. rv = NS_AsyncCopy(stream, sink, target, NS_ASYNCCOPY_VIA_READSEGMENTS,
  428. kBufferSize, // copy segment size
  429. UploadCopyComplete, closure.release());
  430. if (NS_WARN_IF(NS_FAILED(rv))) {
  431. return SendFailedAsyncOpen(rv);
  432. }
  433. mChannel->InternalSetUploadStream(newUploadStream);
  434. } else {
  435. mChannel->InternalSetUploadStream(stream);
  436. }
  437. mChannel->SetUploadStreamHasHeaders(uploadStreamHasHeaders);
  438. }
  439. if (aSynthesizedResponseHead.type() == OptionalHttpResponseHead::TnsHttpResponseHead) {
  440. mParentListener->SetupInterception(aSynthesizedResponseHead.get_nsHttpResponseHead());
  441. mWillSynthesizeResponse = true;
  442. mChannel->SetCouldBeSynthesized();
  443. if (!aSecurityInfoSerialization.IsEmpty()) {
  444. nsCOMPtr<nsISupports> secInfo;
  445. NS_DeserializeObject(aSecurityInfoSerialization, getter_AddRefs(secInfo));
  446. mChannel->OverrideSecurityInfo(secInfo);
  447. }
  448. } else {
  449. nsLoadFlags newLoadFlags;
  450. mChannel->GetLoadFlags(&newLoadFlags);
  451. newLoadFlags |= nsIChannel::LOAD_BYPASS_SERVICE_WORKER;
  452. mChannel->SetLoadFlags(newLoadFlags);
  453. }
  454. nsCOMPtr<nsISupportsPRUint32> cacheKey =
  455. do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID, &rv);
  456. if (NS_FAILED(rv)) {
  457. return SendFailedAsyncOpen(rv);
  458. }
  459. rv = cacheKey->SetData(aCacheKey);
  460. if (NS_FAILED(rv)) {
  461. return SendFailedAsyncOpen(rv);
  462. }
  463. mChannel->SetCacheKey(cacheKey);
  464. mChannel->PreferAlternativeDataType(aPreferredAlternativeType);
  465. mChannel->SetAllowStaleCacheContent(aAllowStaleCacheContent);
  466. mChannel->SetContentType(aContentTypeHint);
  467. if (priority != nsISupportsPriority::PRIORITY_NORMAL) {
  468. mChannel->SetPriority(priority);
  469. }
  470. if (classOfService) {
  471. mChannel->SetClassFlags(classOfService);
  472. }
  473. mChannel->SetRedirectionLimit(redirectionLimit);
  474. mChannel->SetAllowPipelining(allowPipelining);
  475. mChannel->SetAllowSTS(allowSTS);
  476. mChannel->SetThirdPartyFlags(thirdPartyFlags);
  477. mChannel->SetAllowSpdy(allowSpdy);
  478. mChannel->SetAllowAltSvc(allowAltSvc);
  479. mChannel->SetBeConservative(beConservative);
  480. mChannel->SetInitialRwin(aInitialRwin);
  481. mChannel->SetBlockAuthPrompt(aBlockAuthPrompt);
  482. mChannel->SetLaunchServiceWorkerStart(aLaunchServiceWorkerStart);
  483. mChannel->SetLaunchServiceWorkerEnd(aLaunchServiceWorkerEnd);
  484. mChannel->SetDispatchFetchEventStart(aDispatchFetchEventStart);
  485. mChannel->SetDispatchFetchEventEnd(aDispatchFetchEventEnd);
  486. mChannel->SetHandleFetchEventStart(aHandleFetchEventStart);
  487. mChannel->SetHandleFetchEventEnd(aHandleFetchEventEnd);
  488. nsCOMPtr<nsIApplicationCacheChannel> appCacheChan =
  489. do_QueryObject(mChannel);
  490. nsCOMPtr<nsIApplicationCacheService> appCacheService =
  491. do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID);
  492. bool setChooseApplicationCache = chooseApplicationCache;
  493. if (appCacheChan && appCacheService) {
  494. // We might potentially want to drop this flag (that is TRUE by default)
  495. // after we successfully associate the channel with an application cache
  496. // reported by the channel child. Dropping it here may be too early.
  497. appCacheChan->SetInheritApplicationCache(false);
  498. if (!appCacheClientID.IsEmpty()) {
  499. nsCOMPtr<nsIApplicationCache> appCache;
  500. rv = appCacheService->GetApplicationCache(appCacheClientID,
  501. getter_AddRefs(appCache));
  502. if (NS_SUCCEEDED(rv)) {
  503. appCacheChan->SetApplicationCache(appCache);
  504. setChooseApplicationCache = false;
  505. }
  506. }
  507. if (setChooseApplicationCache) {
  508. NeckoOriginAttributes neckoAttrs;
  509. NS_GetOriginAttributes(mChannel, neckoAttrs);
  510. PrincipalOriginAttributes attrs;
  511. attrs.InheritFromNecko(neckoAttrs);
  512. nsCOMPtr<nsIPrincipal> principal =
  513. BasePrincipal::CreateCodebasePrincipal(uri, attrs);
  514. bool chooseAppCache = false;
  515. // This works because we've already called SetNotificationCallbacks and
  516. // done mPBOverride logic by this point.
  517. chooseAppCache = NS_ShouldCheckAppCache(principal, NS_UsePrivateBrowsing(mChannel));
  518. appCacheChan->SetChooseApplicationCache(chooseAppCache);
  519. }
  520. }
  521. nsID requestContextID;
  522. requestContextID.Parse(aRequestContextID.BeginReading());
  523. mChannel->SetRequestContextID(requestContextID);
  524. mSuspendAfterSynthesizeResponse = aSuspendAfterSynthesizeResponse;
  525. if (!delayAsyncOpen) {
  526. InvokeAsyncOpen(NS_OK);
  527. }
  528. return true;
  529. }
  530. bool
  531. HttpChannelParent::ConnectChannel(const uint32_t& registrarId, const bool& shouldIntercept)
  532. {
  533. nsresult rv;
  534. LOG(("HttpChannelParent::ConnectChannel: Looking for a registered channel "
  535. "[this=%p, id=%lu]\n", this, registrarId));
  536. nsCOMPtr<nsIChannel> channel;
  537. rv = NS_LinkRedirectChannels(registrarId, this, getter_AddRefs(channel));
  538. if (NS_FAILED(rv)) {
  539. NS_ERROR("Could not find the http channel to connect its IPC parent");
  540. // This makes the channel delete itself safely. It's the only thing
  541. // we can do now, since this parent channel cannot be used and there is
  542. // no other way to tell the child side there were something wrong.
  543. Delete();
  544. return true;
  545. }
  546. // It's safe to cast here since the found parent-side real channel is ensured
  547. // to be http (nsHttpChannel). ConnectChannel called from HttpChannelParent::Init
  548. // can only be called for http channels. It's bound by ipdl.
  549. mChannel = static_cast<nsHttpChannel*>(channel.get());
  550. LOG((" found channel %p, rv=%08x", mChannel.get(), rv));
  551. nsCOMPtr<nsINetworkInterceptController> controller;
  552. NS_QueryNotificationCallbacks(channel, controller);
  553. RefPtr<HttpChannelParentListener> parentListener = do_QueryObject(controller);
  554. MOZ_ASSERT(parentListener);
  555. parentListener->SetupInterceptionAfterRedirect(shouldIntercept);
  556. if (mPBOverride != kPBOverride_Unset) {
  557. // redirected-to channel may not support PB
  558. nsCOMPtr<nsIPrivateBrowsingChannel> pbChannel = do_QueryObject(mChannel);
  559. if (pbChannel) {
  560. pbChannel->SetPrivate(mPBOverride == kPBOverride_Private ? true : false);
  561. }
  562. }
  563. return true;
  564. }
  565. bool
  566. HttpChannelParent::RecvSetPriority(const uint16_t& priority)
  567. {
  568. LOG(("HttpChannelParent::RecvSetPriority [this=%p, priority=%u]\n",
  569. this, priority));
  570. if (mChannel) {
  571. mChannel->SetPriority(priority);
  572. }
  573. nsCOMPtr<nsISupportsPriority> priorityRedirectChannel =
  574. do_QueryInterface(mRedirectChannel);
  575. if (priorityRedirectChannel)
  576. priorityRedirectChannel->SetPriority(priority);
  577. return true;
  578. }
  579. bool
  580. HttpChannelParent::RecvSetClassOfService(const uint32_t& cos)
  581. {
  582. if (mChannel) {
  583. mChannel->SetClassFlags(cos);
  584. }
  585. return true;
  586. }
  587. bool
  588. HttpChannelParent::RecvSuspend()
  589. {
  590. LOG(("HttpChannelParent::RecvSuspend [this=%p]\n", this));
  591. if (mChannel) {
  592. mChannel->Suspend();
  593. }
  594. return true;
  595. }
  596. bool
  597. HttpChannelParent::RecvResume()
  598. {
  599. LOG(("HttpChannelParent::RecvResume [this=%p]\n", this));
  600. if (mChannel) {
  601. mChannel->Resume();
  602. }
  603. return true;
  604. }
  605. bool
  606. HttpChannelParent::RecvCancel(const nsresult& status)
  607. {
  608. LOG(("HttpChannelParent::RecvCancel [this=%p]\n", this));
  609. // May receive cancel before channel has been constructed!
  610. if (mChannel) {
  611. mChannel->Cancel(status);
  612. }
  613. return true;
  614. }
  615. bool
  616. HttpChannelParent::RecvSetCacheTokenCachedCharset(const nsCString& charset)
  617. {
  618. if (mCacheEntry)
  619. mCacheEntry->SetMetaDataElement("charset", charset.get());
  620. return true;
  621. }
  622. bool
  623. HttpChannelParent::RecvUpdateAssociatedContentSecurity(const int32_t& broken,
  624. const int32_t& no)
  625. {
  626. if (mAssociatedContentSecurity) {
  627. mAssociatedContentSecurity->SetCountSubRequestsBrokenSecurity(broken);
  628. mAssociatedContentSecurity->SetCountSubRequestsNoSecurity(no);
  629. }
  630. return true;
  631. }
  632. bool
  633. HttpChannelParent::RecvRedirect2Verify(const nsresult& result,
  634. const RequestHeaderTuples& changedHeaders,
  635. const uint32_t& loadFlags,
  636. const OptionalURIParams& aAPIRedirectURI,
  637. const OptionalCorsPreflightArgs& aCorsPreflightArgs,
  638. const bool& aChooseAppcache)
  639. {
  640. LOG(("HttpChannelParent::RecvRedirect2Verify [this=%p result=%x]\n",
  641. this, result));
  642. if (NS_SUCCEEDED(result)) {
  643. nsCOMPtr<nsIHttpChannel> newHttpChannel =
  644. do_QueryInterface(mRedirectChannel);
  645. if (newHttpChannel) {
  646. nsCOMPtr<nsIURI> apiRedirectUri = DeserializeURI(aAPIRedirectURI);
  647. if (apiRedirectUri)
  648. newHttpChannel->RedirectTo(apiRedirectUri);
  649. for (uint32_t i = 0; i < changedHeaders.Length(); i++) {
  650. if (changedHeaders[i].mEmpty) {
  651. newHttpChannel->SetEmptyRequestHeader(changedHeaders[i].mHeader);
  652. } else {
  653. newHttpChannel->SetRequestHeader(changedHeaders[i].mHeader,
  654. changedHeaders[i].mValue,
  655. changedHeaders[i].mMerge);
  656. }
  657. }
  658. // A successfully redirected channel must have the LOAD_REPLACE flag.
  659. MOZ_ASSERT(loadFlags & nsIChannel::LOAD_REPLACE);
  660. if (loadFlags & nsIChannel::LOAD_REPLACE) {
  661. newHttpChannel->SetLoadFlags(loadFlags);
  662. }
  663. if (aCorsPreflightArgs.type() == OptionalCorsPreflightArgs::TCorsPreflightArgs) {
  664. nsCOMPtr<nsIHttpChannelInternal> newInternalChannel =
  665. do_QueryInterface(newHttpChannel);
  666. MOZ_RELEASE_ASSERT(newInternalChannel);
  667. const CorsPreflightArgs& args = aCorsPreflightArgs.get_CorsPreflightArgs();
  668. newInternalChannel->SetCorsPreflightParameters(args.unsafeHeaders());
  669. }
  670. nsCOMPtr<nsIApplicationCacheChannel> appCacheChannel =
  671. do_QueryInterface(newHttpChannel);
  672. if (appCacheChannel) {
  673. appCacheChannel->SetChooseApplicationCache(aChooseAppcache);
  674. }
  675. }
  676. }
  677. if (!mRedirectCallback) {
  678. // This should according the logic never happen, log the situation.
  679. if (mReceivedRedirect2Verify)
  680. LOG(("RecvRedirect2Verify[%p]: Duplicate fire", this));
  681. if (mSentRedirect1BeginFailed)
  682. LOG(("RecvRedirect2Verify[%p]: Send to child failed", this));
  683. if (mSentRedirect1Begin && NS_FAILED(result))
  684. LOG(("RecvRedirect2Verify[%p]: Redirect failed", this));
  685. if (mSentRedirect1Begin && NS_SUCCEEDED(result))
  686. LOG(("RecvRedirect2Verify[%p]: Redirect succeeded", this));
  687. if (!mRedirectChannel)
  688. LOG(("RecvRedirect2Verify[%p]: Missing redirect channel", this));
  689. NS_ERROR("Unexpcted call to HttpChannelParent::RecvRedirect2Verify, "
  690. "mRedirectCallback null");
  691. }
  692. mReceivedRedirect2Verify = true;
  693. if (mRedirectCallback) {
  694. LOG(("HttpChannelParent::RecvRedirect2Verify call OnRedirectVerifyCallback"
  695. " [this=%p result=%x, mRedirectCallback=%p]\n",
  696. this, result, mRedirectCallback.get()));
  697. mRedirectCallback->OnRedirectVerifyCallback(result);
  698. mRedirectCallback = nullptr;
  699. }
  700. return true;
  701. }
  702. bool
  703. HttpChannelParent::RecvDocumentChannelCleanup()
  704. {
  705. // From now on only using mAssociatedContentSecurity. Free everything else.
  706. mChannel = nullptr; // Reclaim some memory sooner.
  707. mCacheEntry = nullptr; // Else we'll block other channels reading same URI
  708. return true;
  709. }
  710. bool
  711. HttpChannelParent::RecvMarkOfflineCacheEntryAsForeign()
  712. {
  713. if (mOfflineForeignMarker) {
  714. mOfflineForeignMarker->MarkAsForeign();
  715. mOfflineForeignMarker = 0;
  716. }
  717. return true;
  718. }
  719. class DivertDataAvailableEvent : public ChannelEvent
  720. {
  721. public:
  722. DivertDataAvailableEvent(HttpChannelParent* aParent,
  723. const nsCString& data,
  724. const uint64_t& offset,
  725. const uint32_t& count)
  726. : mParent(aParent)
  727. , mData(data)
  728. , mOffset(offset)
  729. , mCount(count)
  730. {
  731. }
  732. void Run()
  733. {
  734. mParent->DivertOnDataAvailable(mData, mOffset, mCount);
  735. }
  736. private:
  737. HttpChannelParent* mParent;
  738. nsCString mData;
  739. uint64_t mOffset;
  740. uint32_t mCount;
  741. };
  742. bool
  743. HttpChannelParent::RecvDivertOnDataAvailable(const nsCString& data,
  744. const uint64_t& offset,
  745. const uint32_t& count)
  746. {
  747. LOG(("HttpChannelParent::RecvDivertOnDataAvailable [this=%p]\n", this));
  748. MOZ_ASSERT(mParentListener);
  749. if (NS_WARN_IF(!mDivertingFromChild)) {
  750. MOZ_ASSERT(mDivertingFromChild,
  751. "Cannot RecvDivertOnDataAvailable if diverting is not set!");
  752. FailDiversion(NS_ERROR_UNEXPECTED);
  753. return false;
  754. }
  755. // Drop OnDataAvailables if the parent was canceled already.
  756. if (NS_FAILED(mStatus)) {
  757. return true;
  758. }
  759. mEventQ->RunOrEnqueue(new DivertDataAvailableEvent(this, data, offset,
  760. count));
  761. return true;
  762. }
  763. void
  764. HttpChannelParent::DivertOnDataAvailable(const nsCString& data,
  765. const uint64_t& offset,
  766. const uint32_t& count)
  767. {
  768. LOG(("HttpChannelParent::DivertOnDataAvailable [this=%p]\n", this));
  769. MOZ_ASSERT(mParentListener);
  770. if (NS_WARN_IF(!mDivertingFromChild)) {
  771. MOZ_ASSERT(mDivertingFromChild,
  772. "Cannot DivertOnDataAvailable if diverting is not set!");
  773. FailDiversion(NS_ERROR_UNEXPECTED);
  774. return;
  775. }
  776. // Drop OnDataAvailables if the parent was canceled already.
  777. if (NS_FAILED(mStatus)) {
  778. return;
  779. }
  780. nsCOMPtr<nsIInputStream> stringStream;
  781. nsresult rv = NS_NewByteInputStream(getter_AddRefs(stringStream), data.get(),
  782. count, NS_ASSIGNMENT_DEPEND);
  783. if (NS_FAILED(rv)) {
  784. if (mChannel) {
  785. mChannel->Cancel(rv);
  786. }
  787. mStatus = rv;
  788. return;
  789. }
  790. AutoEventEnqueuer ensureSerialDispatch(mEventQ);
  791. rv = mParentListener->OnDataAvailable(mChannel, nullptr, stringStream,
  792. offset, count);
  793. stringStream->Close();
  794. if (NS_FAILED(rv)) {
  795. if (mChannel) {
  796. mChannel->Cancel(rv);
  797. }
  798. mStatus = rv;
  799. }
  800. }
  801. class DivertStopRequestEvent : public ChannelEvent
  802. {
  803. public:
  804. DivertStopRequestEvent(HttpChannelParent* aParent,
  805. const nsresult& statusCode)
  806. : mParent(aParent)
  807. , mStatusCode(statusCode)
  808. {
  809. }
  810. void Run() {
  811. mParent->DivertOnStopRequest(mStatusCode);
  812. }
  813. private:
  814. HttpChannelParent* mParent;
  815. nsresult mStatusCode;
  816. };
  817. bool
  818. HttpChannelParent::RecvDivertOnStopRequest(const nsresult& statusCode)
  819. {
  820. LOG(("HttpChannelParent::RecvDivertOnStopRequest [this=%p]\n", this));
  821. MOZ_ASSERT(mParentListener);
  822. if (NS_WARN_IF(!mDivertingFromChild)) {
  823. MOZ_ASSERT(mDivertingFromChild,
  824. "Cannot RecvDivertOnStopRequest if diverting is not set!");
  825. FailDiversion(NS_ERROR_UNEXPECTED);
  826. return false;
  827. }
  828. mEventQ->RunOrEnqueue(new DivertStopRequestEvent(this, statusCode));
  829. return true;
  830. }
  831. void
  832. HttpChannelParent::DivertOnStopRequest(const nsresult& statusCode)
  833. {
  834. LOG(("HttpChannelParent::DivertOnStopRequest [this=%p]\n", this));
  835. MOZ_ASSERT(mParentListener);
  836. if (NS_WARN_IF(!mDivertingFromChild)) {
  837. MOZ_ASSERT(mDivertingFromChild,
  838. "Cannot DivertOnStopRequest if diverting is not set!");
  839. FailDiversion(NS_ERROR_UNEXPECTED);
  840. return;
  841. }
  842. // Honor the channel's status even if the underlying transaction completed.
  843. nsresult status = NS_FAILED(mStatus) ? mStatus : statusCode;
  844. // Reset fake pending status in case OnStopRequest has already been called.
  845. if (mChannel) {
  846. mChannel->ForcePending(false);
  847. }
  848. AutoEventEnqueuer ensureSerialDispatch(mEventQ);
  849. mParentListener->OnStopRequest(mChannel, nullptr, status);
  850. }
  851. class DivertCompleteEvent : public ChannelEvent
  852. {
  853. public:
  854. explicit DivertCompleteEvent(HttpChannelParent* aParent)
  855. : mParent(aParent)
  856. {
  857. }
  858. void Run() {
  859. mParent->DivertComplete();
  860. }
  861. private:
  862. HttpChannelParent* mParent;
  863. };
  864. bool
  865. HttpChannelParent::RecvDivertComplete()
  866. {
  867. LOG(("HttpChannelParent::RecvDivertComplete [this=%p]\n", this));
  868. MOZ_ASSERT(mParentListener);
  869. if (NS_WARN_IF(!mDivertingFromChild)) {
  870. MOZ_ASSERT(mDivertingFromChild,
  871. "Cannot RecvDivertComplete if diverting is not set!");
  872. FailDiversion(NS_ERROR_UNEXPECTED);
  873. return false;
  874. }
  875. mEventQ->RunOrEnqueue(new DivertCompleteEvent(this));
  876. return true;
  877. }
  878. void
  879. HttpChannelParent::DivertComplete()
  880. {
  881. LOG(("HttpChannelParent::DivertComplete [this=%p]\n", this));
  882. MOZ_ASSERT(mParentListener);
  883. if (NS_WARN_IF(!mDivertingFromChild)) {
  884. MOZ_ASSERT(mDivertingFromChild,
  885. "Cannot DivertComplete if diverting is not set!");
  886. FailDiversion(NS_ERROR_UNEXPECTED);
  887. return;
  888. }
  889. nsresult rv = ResumeForDiversion();
  890. if (NS_WARN_IF(NS_FAILED(rv))) {
  891. FailDiversion(NS_ERROR_UNEXPECTED);
  892. return;
  893. }
  894. mParentListener = nullptr;
  895. }
  896. void
  897. HttpChannelParent::MaybeFlushPendingDiversion()
  898. {
  899. if (!mPendingDiversion) {
  900. return;
  901. }
  902. mPendingDiversion = false;
  903. nsresult rv = SuspendForDiversion();
  904. if (NS_WARN_IF(NS_FAILED(rv))) {
  905. return;
  906. }
  907. if (mDivertListener) {
  908. DivertTo(mDivertListener);
  909. }
  910. return;
  911. }
  912. void
  913. HttpChannelParent::ResponseSynthesized()
  914. {
  915. // Suspend now even though the FinishSynthesizeResponse runnable has
  916. // not executed. We want to suspend after we get far enough to trigger
  917. // the synthesis, but not actually allow the nsHttpChannel to trigger
  918. // any OnStartRequests().
  919. if (mSuspendAfterSynthesizeResponse) {
  920. mChannel->Suspend();
  921. }
  922. mWillSynthesizeResponse = false;
  923. MaybeFlushPendingDiversion();
  924. }
  925. bool
  926. HttpChannelParent::RecvRemoveCorsPreflightCacheEntry(const URIParams& uri,
  927. const mozilla::ipc::PrincipalInfo& requestingPrincipal)
  928. {
  929. nsCOMPtr<nsIURI> deserializedURI = DeserializeURI(uri);
  930. if (!deserializedURI) {
  931. return false;
  932. }
  933. nsCOMPtr<nsIPrincipal> principal =
  934. PrincipalInfoToPrincipal(requestingPrincipal);
  935. if (!principal) {
  936. return false;
  937. }
  938. nsCORSListenerProxy::RemoveFromCorsPreflightCache(deserializedURI,
  939. principal);
  940. return true;
  941. }
  942. //-----------------------------------------------------------------------------
  943. // HttpChannelParent::nsIRequestObserver
  944. //-----------------------------------------------------------------------------
  945. NS_IMETHODIMP
  946. HttpChannelParent::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
  947. {
  948. LOG(("HttpChannelParent::OnStartRequest [this=%p, aRequest=%p]\n",
  949. this, aRequest));
  950. MOZ_RELEASE_ASSERT(!mDivertingFromChild,
  951. "Cannot call OnStartRequest if diverting is set!");
  952. // We can't cast here since the new channel can be a redirect to a different
  953. // schema. We must query the channel implementation through a special method.
  954. nsHttpChannel *chan = nullptr;
  955. nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal(do_QueryInterface(aRequest));
  956. if (httpChannelInternal) {
  957. chan = httpChannelInternal->QueryHttpChannelImpl();
  958. }
  959. if (!chan) {
  960. LOG((" aRequest is not nsHttpChannel"));
  961. NS_ERROR("Expecting only nsHttpChannel as aRequest in HttpChannelParent::OnStartRequest");
  962. return NS_ERROR_UNEXPECTED;
  963. }
  964. MOZ_ASSERT(mChannel == chan,
  965. "HttpChannelParent getting OnStartRequest from a different nsHttpChannel instance");
  966. nsHttpResponseHead *responseHead = chan->GetResponseHead();
  967. nsHttpRequestHead *requestHead = chan->GetRequestHead();
  968. bool isFromCache = false;
  969. chan->IsFromCache(&isFromCache);
  970. uint32_t expirationTime = nsICacheEntry::NO_EXPIRATION_TIME;
  971. chan->GetCacheTokenExpirationTime(&expirationTime);
  972. nsCString cachedCharset;
  973. chan->GetCacheTokenCachedCharset(cachedCharset);
  974. bool loadedFromApplicationCache;
  975. chan->GetLoadedFromApplicationCache(&loadedFromApplicationCache);
  976. if (loadedFromApplicationCache) {
  977. mOfflineForeignMarker = chan->GetOfflineCacheEntryAsForeignMarker();
  978. nsCOMPtr<nsIApplicationCache> appCache;
  979. chan->GetApplicationCache(getter_AddRefs(appCache));
  980. nsCString appCacheGroupId;
  981. nsCString appCacheClientId;
  982. appCache->GetGroupID(appCacheGroupId);
  983. appCache->GetClientID(appCacheClientId);
  984. if (mIPCClosed ||
  985. !SendAssociateApplicationCache(appCacheGroupId, appCacheClientId))
  986. {
  987. return NS_ERROR_UNEXPECTED;
  988. }
  989. }
  990. nsCOMPtr<nsIEncodedChannel> encodedChannel = do_QueryInterface(aRequest);
  991. if (encodedChannel)
  992. encodedChannel->SetApplyConversion(false);
  993. // Keep the cache entry for future use in RecvSetCacheTokenCachedCharset().
  994. // It could be already released by nsHttpChannel at that time.
  995. nsCOMPtr<nsISupports> cacheEntry;
  996. chan->GetCacheToken(getter_AddRefs(cacheEntry));
  997. mCacheEntry = do_QueryInterface(cacheEntry);
  998. nsresult channelStatus = NS_OK;
  999. chan->GetStatus(&channelStatus);
  1000. nsCString secInfoSerialization;
  1001. UpdateAndSerializeSecurityInfo(secInfoSerialization);
  1002. uint8_t redirectCount = 0;
  1003. chan->GetRedirectCount(&redirectCount);
  1004. nsCOMPtr<nsISupports> cacheKey;
  1005. chan->GetCacheKey(getter_AddRefs(cacheKey));
  1006. uint32_t cacheKeyValue = 0;
  1007. if (cacheKey) {
  1008. nsCOMPtr<nsISupportsPRUint32> container = do_QueryInterface(cacheKey);
  1009. if (!container) {
  1010. return NS_ERROR_ILLEGAL_VALUE;
  1011. }
  1012. nsresult rv = container->GetData(&cacheKeyValue);
  1013. if (NS_FAILED(rv)) {
  1014. return rv;
  1015. }
  1016. }
  1017. nsAutoCString altDataType;
  1018. chan->GetAlternativeDataType(altDataType);
  1019. // !!! We need to lock headers and please don't forget to unlock them !!!
  1020. requestHead->Enter();
  1021. nsresult rv = NS_OK;
  1022. if (mIPCClosed ||
  1023. !SendOnStartRequest(channelStatus,
  1024. responseHead ? *responseHead : nsHttpResponseHead(),
  1025. !!responseHead,
  1026. requestHead->Headers(),
  1027. isFromCache,
  1028. mCacheEntry ? true : false,
  1029. expirationTime, cachedCharset, secInfoSerialization,
  1030. chan->GetSelfAddr(), chan->GetPeerAddr(),
  1031. redirectCount,
  1032. cacheKeyValue,
  1033. altDataType))
  1034. {
  1035. rv = NS_ERROR_UNEXPECTED;
  1036. }
  1037. requestHead->Exit();
  1038. return rv;
  1039. }
  1040. NS_IMETHODIMP
  1041. HttpChannelParent::OnStopRequest(nsIRequest *aRequest,
  1042. nsISupports *aContext,
  1043. nsresult aStatusCode)
  1044. {
  1045. LOG(("HttpChannelParent::OnStopRequest: [this=%p aRequest=%p status=%x]\n",
  1046. this, aRequest, aStatusCode));
  1047. MOZ_RELEASE_ASSERT(!mDivertingFromChild,
  1048. "Cannot call OnStopRequest if diverting is set!");
  1049. ResourceTimingStruct timing;
  1050. mChannel->GetDomainLookupStart(&timing.domainLookupStart);
  1051. mChannel->GetDomainLookupEnd(&timing.domainLookupEnd);
  1052. mChannel->GetConnectStart(&timing.connectStart);
  1053. mChannel->GetSecureConnectionStart(&timing.secureConnectionStart);
  1054. mChannel->GetConnectEnd(&timing.connectEnd);
  1055. mChannel->GetRequestStart(&timing.requestStart);
  1056. mChannel->GetResponseStart(&timing.responseStart);
  1057. mChannel->GetResponseEnd(&timing.responseEnd);
  1058. mChannel->GetAsyncOpen(&timing.fetchStart);
  1059. mChannel->GetRedirectStart(&timing.redirectStart);
  1060. mChannel->GetRedirectEnd(&timing.redirectEnd);
  1061. mChannel->GetTransferSize(&timing.transferSize);
  1062. mChannel->GetEncodedBodySize(&timing.encodedBodySize);
  1063. // decodedBodySize can be computed in the child process so it doesn't need
  1064. // to be passed down.
  1065. mChannel->GetProtocolVersion(timing.protocolVersion);
  1066. mChannel->GetCacheReadStart(&timing.cacheReadStart);
  1067. mChannel->GetCacheReadEnd(&timing.cacheReadEnd);
  1068. if (mIPCClosed || !SendOnStopRequest(aStatusCode, timing))
  1069. return NS_ERROR_UNEXPECTED;
  1070. return NS_OK;
  1071. }
  1072. //-----------------------------------------------------------------------------
  1073. // HttpChannelParent::nsIStreamListener
  1074. //-----------------------------------------------------------------------------
  1075. NS_IMETHODIMP
  1076. HttpChannelParent::OnDataAvailable(nsIRequest *aRequest,
  1077. nsISupports *aContext,
  1078. nsIInputStream *aInputStream,
  1079. uint64_t aOffset,
  1080. uint32_t aCount)
  1081. {
  1082. LOG(("HttpChannelParent::OnDataAvailable [this=%p aRequest=%p]\n",
  1083. this, aRequest));
  1084. MOZ_RELEASE_ASSERT(!mDivertingFromChild,
  1085. "Cannot call OnDataAvailable if diverting is set!");
  1086. nsresult channelStatus = NS_OK;
  1087. mChannel->GetStatus(&channelStatus);
  1088. static uint32_t const kCopyChunkSize = 128 * 1024;
  1089. uint32_t toRead = std::min<uint32_t>(aCount, kCopyChunkSize);
  1090. nsCString data;
  1091. if (!data.SetCapacity(toRead, fallible)) {
  1092. LOG((" out of memory!"));
  1093. return NS_ERROR_OUT_OF_MEMORY;
  1094. }
  1095. while (aCount) {
  1096. nsresult rv = NS_ReadInputStreamToString(aInputStream, data, toRead);
  1097. if (NS_FAILED(rv)) {
  1098. return rv;
  1099. }
  1100. // OnDataAvailable is always preceded by OnStatus/OnProgress calls that set
  1101. // mStoredStatus/mStoredProgress(Max) to appropriate values, unless
  1102. // LOAD_BACKGROUND set. In that case, they'll have garbage values, but
  1103. // child doesn't use them.
  1104. if (mIPCClosed || !SendOnTransportAndData(channelStatus, mStoredStatus,
  1105. mStoredProgress, mStoredProgressMax,
  1106. aOffset, toRead, data)) {
  1107. return NS_ERROR_UNEXPECTED;
  1108. }
  1109. aOffset += toRead;
  1110. aCount -= toRead;
  1111. toRead = std::min<uint32_t>(aCount, kCopyChunkSize);
  1112. }
  1113. return NS_OK;
  1114. }
  1115. //-----------------------------------------------------------------------------
  1116. // HttpChannelParent::nsIProgressEventSink
  1117. //-----------------------------------------------------------------------------
  1118. NS_IMETHODIMP
  1119. HttpChannelParent::OnProgress(nsIRequest *aRequest,
  1120. nsISupports *aContext,
  1121. int64_t aProgress,
  1122. int64_t aProgressMax)
  1123. {
  1124. // OnStatus has always just set mStoredStatus. If it indicates this precedes
  1125. // OnDataAvailable, store and ODA will send to child.
  1126. if (mStoredStatus == NS_NET_STATUS_RECEIVING_FROM ||
  1127. mStoredStatus == NS_NET_STATUS_READING)
  1128. {
  1129. mStoredProgress = aProgress;
  1130. mStoredProgressMax = aProgressMax;
  1131. } else {
  1132. // Send OnProgress events to the child for data upload progress notifications
  1133. // (i.e. status == NS_NET_STATUS_SENDING_TO) or if the channel has
  1134. // LOAD_BACKGROUND set.
  1135. if (mIPCClosed || !SendOnProgress(aProgress, aProgressMax))
  1136. return NS_ERROR_UNEXPECTED;
  1137. }
  1138. return NS_OK;
  1139. }
  1140. NS_IMETHODIMP
  1141. HttpChannelParent::OnStatus(nsIRequest *aRequest,
  1142. nsISupports *aContext,
  1143. nsresult aStatus,
  1144. const char16_t *aStatusArg)
  1145. {
  1146. // If this precedes OnDataAvailable, store and ODA will send to child.
  1147. if (aStatus == NS_NET_STATUS_RECEIVING_FROM ||
  1148. aStatus == NS_NET_STATUS_READING)
  1149. {
  1150. mStoredStatus = aStatus;
  1151. return NS_OK;
  1152. }
  1153. // Otherwise, send to child now
  1154. if (mIPCClosed || !SendOnStatus(aStatus))
  1155. return NS_ERROR_UNEXPECTED;
  1156. return NS_OK;
  1157. }
  1158. //-----------------------------------------------------------------------------
  1159. // HttpChannelParent::nsIParentChannel
  1160. //-----------------------------------------------------------------------------
  1161. NS_IMETHODIMP
  1162. HttpChannelParent::SetParentListener(HttpChannelParentListener* aListener)
  1163. {
  1164. LOG(("HttpChannelParent::SetParentListener [this=%p aListener=%p]\n",
  1165. this, aListener));
  1166. MOZ_ASSERT(aListener);
  1167. MOZ_ASSERT(!mParentListener, "SetParentListener should only be called for "
  1168. "new HttpChannelParents after a redirect, when "
  1169. "mParentListener is null.");
  1170. mParentListener = aListener;
  1171. return NS_OK;
  1172. }
  1173. NS_IMETHODIMP
  1174. HttpChannelParent::NotifyTrackingProtectionDisabled()
  1175. {
  1176. if (!mIPCClosed)
  1177. Unused << SendNotifyTrackingProtectionDisabled();
  1178. return NS_OK;
  1179. }
  1180. NS_IMETHODIMP
  1181. HttpChannelParent::Delete()
  1182. {
  1183. if (!mIPCClosed)
  1184. Unused << DoSendDeleteSelf();
  1185. return NS_OK;
  1186. }
  1187. //-----------------------------------------------------------------------------
  1188. // HttpChannelParent::nsIParentRedirectingChannel
  1189. //-----------------------------------------------------------------------------
  1190. NS_IMETHODIMP
  1191. HttpChannelParent::StartRedirect(uint32_t registrarId,
  1192. nsIChannel* newChannel,
  1193. uint32_t redirectFlags,
  1194. nsIAsyncVerifyRedirectCallback* callback)
  1195. {
  1196. LOG(("HttpChannelParent::StartRedirect [this=%p, registrarId=%lu "
  1197. "newChannel=%p callback=%p]\n", this, registrarId, newChannel,
  1198. callback));
  1199. if (mIPCClosed)
  1200. return NS_BINDING_ABORTED;
  1201. nsCOMPtr<nsIURI> newURI;
  1202. newChannel->GetURI(getter_AddRefs(newURI));
  1203. URIParams uriParams;
  1204. SerializeURI(newURI, uriParams);
  1205. nsCString secInfoSerialization;
  1206. UpdateAndSerializeSecurityInfo(secInfoSerialization);
  1207. // If the channel is a HTTP channel, we also want to inform the child
  1208. // about the parent's channelId attribute, so that both parent and child
  1209. // share the same ID. Useful for monitoring channel activity in devtools.
  1210. nsAutoCString channelId;
  1211. nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(newChannel);
  1212. if (httpChannel) {
  1213. nsresult rv = httpChannel->GetChannelId(channelId);
  1214. NS_ENSURE_SUCCESS(rv, NS_BINDING_ABORTED);
  1215. }
  1216. nsHttpResponseHead *responseHead = mChannel->GetResponseHead();
  1217. bool result = false;
  1218. if (!mIPCClosed) {
  1219. result = SendRedirect1Begin(registrarId, uriParams, redirectFlags,
  1220. responseHead ? *responseHead
  1221. : nsHttpResponseHead(),
  1222. secInfoSerialization,
  1223. channelId);
  1224. }
  1225. if (!result) {
  1226. // Bug 621446 investigation
  1227. mSentRedirect1BeginFailed = true;
  1228. return NS_BINDING_ABORTED;
  1229. }
  1230. // Bug 621446 investigation
  1231. mSentRedirect1Begin = true;
  1232. // Result is handled in RecvRedirect2Verify above
  1233. mRedirectChannel = newChannel;
  1234. mRedirectCallback = callback;
  1235. return NS_OK;
  1236. }
  1237. NS_IMETHODIMP
  1238. HttpChannelParent::CompleteRedirect(bool succeeded)
  1239. {
  1240. LOG(("HttpChannelParent::CompleteRedirect [this=%p succeeded=%d]\n",
  1241. this, succeeded));
  1242. if (succeeded && !mIPCClosed) {
  1243. // TODO: check return value: assume child dead if failed
  1244. Unused << SendRedirect3Complete();
  1245. }
  1246. mRedirectChannel = nullptr;
  1247. return NS_OK;
  1248. }
  1249. //-----------------------------------------------------------------------------
  1250. // HttpChannelParent::ADivertableParentChannel
  1251. //-----------------------------------------------------------------------------
  1252. nsresult
  1253. HttpChannelParent::SuspendForDiversion()
  1254. {
  1255. LOG(("HttpChannelParent::SuspendForDiversion [this=%p]\n", this));
  1256. MOZ_ASSERT(mChannel);
  1257. MOZ_ASSERT(mParentListener);
  1258. // If we're in the process of opening a synthesized response, we must wait
  1259. // to perform the diversion. Some of our diversion listeners clear callbacks
  1260. // which breaks the synthesis process.
  1261. if (mWillSynthesizeResponse) {
  1262. mPendingDiversion = true;
  1263. return NS_OK;
  1264. }
  1265. if (NS_WARN_IF(mDivertingFromChild)) {
  1266. MOZ_ASSERT(!mDivertingFromChild, "Already suspended for diversion!");
  1267. return NS_ERROR_UNEXPECTED;
  1268. }
  1269. // MessageDiversionStarted call will suspend mEventQ as many times as the
  1270. // channel has been suspended, so that channel and this queue are in sync.
  1271. mChannel->MessageDiversionStarted(this);
  1272. nsresult rv = NS_OK;
  1273. // Try suspending the channel. Allow it to fail, since OnStopRequest may have
  1274. // been called and thus the channel may not be pending. If we've already
  1275. // automatically suspended after synthesizing the response, then we don't
  1276. // need to suspend again here.
  1277. if (!mSuspendAfterSynthesizeResponse) {
  1278. // We need to suspend only nsHttpChannel (i.e. we should not suspend
  1279. // mEventQ). Therefore we call mChannel->SuspendInternal() and not
  1280. // mChannel->Suspend().
  1281. // We are suspending only nsHttpChannel here because we want to stop
  1282. // OnDataAvailable until diversion is over. At the same time we should
  1283. // send the diverted OnDataAvailable-s to the listeners and not queue them
  1284. // in mEventQ.
  1285. rv = mChannel->SuspendInternal();
  1286. MOZ_ASSERT(NS_SUCCEEDED(rv) || rv == NS_ERROR_NOT_AVAILABLE);
  1287. mSuspendedForDiversion = NS_SUCCEEDED(rv);
  1288. } else {
  1289. // Take ownership of the automatic suspend that occurred after synthesizing
  1290. // the response.
  1291. mSuspendedForDiversion = true;
  1292. // If mSuspendAfterSynthesizeResponse is true channel has been already
  1293. // suspended. From comment above mSuspendedForDiversion takes the ownership
  1294. // of this suspend, therefore mEventQ should not be suspened so we need to
  1295. // resume it once.
  1296. mEventQ->Resume();
  1297. }
  1298. rv = mParentListener->SuspendForDiversion();
  1299. MOZ_ASSERT(NS_SUCCEEDED(rv));
  1300. // Once this is set, no more OnStart/OnData/OnStop callbacks should be sent
  1301. // to the child.
  1302. mDivertingFromChild = true;
  1303. return NS_OK;
  1304. }
  1305. nsresult
  1306. HttpChannelParent::SuspendMessageDiversion()
  1307. {
  1308. LOG(("HttpChannelParent::SuspendMessageDiversion [this=%p]", this));
  1309. // This only needs to suspend message queue.
  1310. mEventQ->Suspend();
  1311. return NS_OK;
  1312. }
  1313. nsresult
  1314. HttpChannelParent::ResumeMessageDiversion()
  1315. {
  1316. LOG(("HttpChannelParent::SuspendMessageDiversion [this=%p]", this));
  1317. // This only needs to resumes message queue.
  1318. mEventQ->Resume();
  1319. return NS_OK;
  1320. }
  1321. /* private, supporting function for ADivertableParentChannel */
  1322. nsresult
  1323. HttpChannelParent::ResumeForDiversion()
  1324. {
  1325. LOG(("HttpChannelParent::ResumeForDiversion [this=%p]\n", this));
  1326. MOZ_ASSERT(mChannel);
  1327. if (NS_WARN_IF(!mDivertingFromChild)) {
  1328. MOZ_ASSERT(mDivertingFromChild,
  1329. "Cannot ResumeForDiversion if not diverting!");
  1330. return NS_ERROR_UNEXPECTED;
  1331. }
  1332. mChannel->MessageDiversionStop();
  1333. if (mSuspendedForDiversion) {
  1334. // The nsHttpChannel will deliver remaining OnData/OnStop for the transfer.
  1335. nsresult rv = mChannel->ResumeInternal();
  1336. if (NS_WARN_IF(NS_FAILED(rv))) {
  1337. FailDiversion(NS_ERROR_UNEXPECTED, true);
  1338. return rv;
  1339. }
  1340. mSuspendedForDiversion = false;
  1341. }
  1342. if (NS_WARN_IF(mIPCClosed || !DoSendDeleteSelf())) {
  1343. FailDiversion(NS_ERROR_UNEXPECTED);
  1344. return NS_ERROR_UNEXPECTED;
  1345. }
  1346. return NS_OK;
  1347. }
  1348. void
  1349. HttpChannelParent::DivertTo(nsIStreamListener *aListener)
  1350. {
  1351. LOG(("HttpChannelParent::DivertTo [this=%p aListener=%p]\n",
  1352. this, aListener));
  1353. MOZ_ASSERT(mParentListener);
  1354. // If we're in the process of opening a synthesized response, we must wait
  1355. // to perform the diversion. Some of our diversion listeners clear callbacks
  1356. // which breaks the synthesis process.
  1357. if (mWillSynthesizeResponse) {
  1358. // We should already have started pending the diversion when
  1359. // SuspendForDiversion() was called.
  1360. MOZ_ASSERT(mPendingDiversion);
  1361. mDivertListener = aListener;
  1362. return;
  1363. }
  1364. if (NS_WARN_IF(!mDivertingFromChild)) {
  1365. MOZ_ASSERT(mDivertingFromChild,
  1366. "Cannot DivertTo new listener if diverting is not set!");
  1367. return;
  1368. }
  1369. mDivertListener = aListener;
  1370. // Call OnStartRequest and SendDivertMessages asynchronously to avoid
  1371. // reentering client context.
  1372. NS_DispatchToCurrentThread(
  1373. NewRunnableMethod(this, &HttpChannelParent::StartDiversion));
  1374. return;
  1375. }
  1376. void
  1377. HttpChannelParent::StartDiversion()
  1378. {
  1379. LOG(("HttpChannelParent::StartDiversion [this=%p]\n", this));
  1380. if (NS_WARN_IF(!mDivertingFromChild)) {
  1381. MOZ_ASSERT(mDivertingFromChild,
  1382. "Cannot StartDiversion if diverting is not set!");
  1383. return;
  1384. }
  1385. // Fake pending status in case OnStopRequest has already been called.
  1386. if (mChannel) {
  1387. mChannel->ForcePending(true);
  1388. }
  1389. {
  1390. AutoEventEnqueuer ensureSerialDispatch(mEventQ);
  1391. // Call OnStartRequest for the "DivertTo" listener.
  1392. nsresult rv = mDivertListener->OnStartRequest(mChannel, nullptr);
  1393. if (NS_FAILED(rv)) {
  1394. if (mChannel) {
  1395. mChannel->Cancel(rv);
  1396. }
  1397. mStatus = rv;
  1398. }
  1399. }
  1400. mDivertedOnStartRequest = true;
  1401. // After OnStartRequest has been called, setup content decoders if needed.
  1402. //
  1403. // Create a content conversion chain based on mDivertListener and update
  1404. // mDivertListener.
  1405. nsCOMPtr<nsIStreamListener> converterListener;
  1406. mChannel->DoApplyContentConversions(mDivertListener,
  1407. getter_AddRefs(converterListener));
  1408. if (converterListener) {
  1409. mDivertListener = converterListener.forget();
  1410. }
  1411. // Now mParentListener can be diverted to mDivertListener.
  1412. DebugOnly<nsresult> rvdbg = mParentListener->DivertTo(mDivertListener);
  1413. MOZ_ASSERT(NS_SUCCEEDED(rvdbg));
  1414. mDivertListener = nullptr;
  1415. if (NS_WARN_IF(mIPCClosed || !SendFlushedForDiversion())) {
  1416. FailDiversion(NS_ERROR_UNEXPECTED);
  1417. return;
  1418. }
  1419. // The listener chain should now be setup; tell HttpChannelChild to divert
  1420. // the OnDataAvailables and OnStopRequest to this HttpChannelParent.
  1421. if (NS_WARN_IF(mIPCClosed || !SendDivertMessages())) {
  1422. FailDiversion(NS_ERROR_UNEXPECTED);
  1423. return;
  1424. }
  1425. }
  1426. class HTTPFailDiversionEvent : public Runnable
  1427. {
  1428. public:
  1429. HTTPFailDiversionEvent(HttpChannelParent *aChannelParent,
  1430. nsresult aErrorCode,
  1431. bool aSkipResume)
  1432. : mChannelParent(aChannelParent)
  1433. , mErrorCode(aErrorCode)
  1434. , mSkipResume(aSkipResume)
  1435. {
  1436. MOZ_RELEASE_ASSERT(aChannelParent);
  1437. MOZ_RELEASE_ASSERT(NS_FAILED(aErrorCode));
  1438. }
  1439. NS_IMETHOD Run() override
  1440. {
  1441. mChannelParent->NotifyDiversionFailed(mErrorCode, mSkipResume);
  1442. return NS_OK;
  1443. }
  1444. private:
  1445. RefPtr<HttpChannelParent> mChannelParent;
  1446. nsresult mErrorCode;
  1447. bool mSkipResume;
  1448. };
  1449. void
  1450. HttpChannelParent::FailDiversion(nsresult aErrorCode,
  1451. bool aSkipResume)
  1452. {
  1453. MOZ_RELEASE_ASSERT(NS_FAILED(aErrorCode));
  1454. MOZ_RELEASE_ASSERT(mDivertingFromChild);
  1455. MOZ_RELEASE_ASSERT(mParentListener);
  1456. MOZ_RELEASE_ASSERT(mChannel);
  1457. NS_DispatchToCurrentThread(
  1458. new HTTPFailDiversionEvent(this, aErrorCode, aSkipResume));
  1459. }
  1460. void
  1461. HttpChannelParent::NotifyDiversionFailed(nsresult aErrorCode,
  1462. bool aSkipResume)
  1463. {
  1464. LOG(("HttpChannelParent::NotifyDiversionFailed [this=%p aErrorCode=%x]\n",
  1465. this, aErrorCode));
  1466. MOZ_RELEASE_ASSERT(NS_FAILED(aErrorCode));
  1467. MOZ_RELEASE_ASSERT(mDivertingFromChild);
  1468. MOZ_RELEASE_ASSERT(mParentListener);
  1469. MOZ_RELEASE_ASSERT(mChannel);
  1470. mChannel->Cancel(aErrorCode);
  1471. mChannel->ForcePending(false);
  1472. bool isPending = false;
  1473. nsresult rv = mChannel->IsPending(&isPending);
  1474. MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
  1475. // Resume only if we suspended earlier.
  1476. if (mSuspendedForDiversion) {
  1477. mChannel->ResumeInternal();
  1478. }
  1479. // Channel has already sent OnStartRequest to the child, so ensure that we
  1480. // call it here if it hasn't already been called.
  1481. if (!mDivertedOnStartRequest) {
  1482. mChannel->ForcePending(true);
  1483. mParentListener->OnStartRequest(mChannel, nullptr);
  1484. mChannel->ForcePending(false);
  1485. }
  1486. // If the channel is pending, it will call OnStopRequest itself; otherwise, do
  1487. // it here.
  1488. if (!isPending) {
  1489. mParentListener->OnStopRequest(mChannel, nullptr, aErrorCode);
  1490. }
  1491. mParentListener = nullptr;
  1492. mChannel = nullptr;
  1493. if (!mIPCClosed) {
  1494. Unused << DoSendDeleteSelf();
  1495. }
  1496. }
  1497. nsresult
  1498. HttpChannelParent::OpenAlternativeOutputStream(const nsACString & type, nsIOutputStream * *_retval)
  1499. {
  1500. // We need to make sure the child does not call SendDocumentChannelCleanup()
  1501. // before opening the altOutputStream, because that clears mCacheEntry.
  1502. if (!mCacheEntry) {
  1503. return NS_ERROR_NOT_AVAILABLE;
  1504. }
  1505. return mCacheEntry->OpenAlternativeOutputStream(type, _retval);
  1506. }
  1507. NS_IMETHODIMP
  1508. HttpChannelParent::GetAuthPrompt(uint32_t aPromptReason, const nsIID& iid,
  1509. void** aResult)
  1510. {
  1511. nsCOMPtr<nsIAuthPrompt2> prompt =
  1512. new NeckoParent::NestedFrameAuthPrompt(Manager(), mNestedFrameId);
  1513. prompt.forget(aResult);
  1514. return NS_OK;
  1515. }
  1516. void
  1517. HttpChannelParent::UpdateAndSerializeSecurityInfo(nsACString& aSerializedSecurityInfoOut)
  1518. {
  1519. nsCOMPtr<nsISupports> secInfoSupp;
  1520. mChannel->GetSecurityInfo(getter_AddRefs(secInfoSupp));
  1521. if (secInfoSupp) {
  1522. mAssociatedContentSecurity = do_QueryInterface(secInfoSupp);
  1523. nsCOMPtr<nsISerializable> secInfoSer = do_QueryInterface(secInfoSupp);
  1524. if (secInfoSer) {
  1525. NS_SerializeToString(secInfoSer, aSerializedSecurityInfoOut);
  1526. }
  1527. }
  1528. }
  1529. bool
  1530. HttpChannelParent::DoSendDeleteSelf()
  1531. {
  1532. mIPCClosed = true;
  1533. bool rv = SendDeleteSelf();
  1534. return rv;
  1535. }
  1536. bool
  1537. HttpChannelParent::RecvDeletingChannel()
  1538. {
  1539. // We need to ensure that the parent channel will not be sending any more IPC
  1540. // messages after this, as the child is going away. DoSendDeleteSelf will
  1541. // set mIPCClosed = true;
  1542. return DoSendDeleteSelf();
  1543. }
  1544. bool
  1545. HttpChannelParent::RecvFinishInterceptedRedirect()
  1546. {
  1547. // We make sure not to send any more messages until the IPC channel is torn
  1548. // down by the child.
  1549. mIPCClosed = true;
  1550. return SendFinishInterceptedRedirect();
  1551. }
  1552. //-----------------------------------------------------------------------------
  1553. // HttpChannelSecurityWarningReporter
  1554. //-----------------------------------------------------------------------------
  1555. nsresult
  1556. HttpChannelParent::ReportSecurityMessage(const nsAString& aMessageTag,
  1557. const nsAString& aMessageCategory)
  1558. {
  1559. if (mIPCClosed ||
  1560. NS_WARN_IF(!SendReportSecurityMessage(nsString(aMessageTag),
  1561. nsString(aMessageCategory)))) {
  1562. return NS_ERROR_UNEXPECTED;
  1563. }
  1564. return NS_OK;
  1565. }
  1566. NS_IMETHODIMP
  1567. HttpChannelParent::IssueWarning(uint32_t aWarning, bool aAsError)
  1568. {
  1569. Unused << SendIssueDeprecationWarning(aWarning, aAsError);
  1570. return NS_OK;
  1571. }
  1572. } // namespace net
  1573. } // namespace mozilla