NS_IMETHODIMP nsBaseChannel::Open(nsIInputStream **result) { NS_ENSURE_TRUE(mURI, NS_ERROR_NOT_INITIALIZED); NS_ENSURE_TRUE(!mPump, NS_ERROR_IN_PROGRESS); NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_IN_PROGRESS); nsCOMPtr<nsIChannel> chan; nsresult rv = OpenContentStream(false, result, getter_AddRefs(chan)); NS_ASSERTION(!chan || !*result, "Got both a channel and a stream?"); if (NS_SUCCEEDED(rv) && chan) { rv = Redirect(chan, nsIChannelEventSink::REDIRECT_INTERNAL, false); if (NS_FAILED(rv)) return rv; rv = chan->Open(result); } else if (rv == NS_ERROR_NOT_IMPLEMENTED) return NS_ImplementChannelOpen(this, result); if (NS_SUCCEEDED(rv)) { mWasOpened = true; ClassifyURI(); } return rv; }
NS_IMETHODIMP nsBaseChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt) { MOZ_ASSERT(!mLoadInfo || mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone() || (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL && nsContentUtils::IsSystemPrincipal(mLoadInfo->LoadingPrincipal())), "security flags in loadInfo but asyncOpen2() not called"); NS_ENSURE_TRUE(mURI, NS_ERROR_NOT_INITIALIZED); NS_ENSURE_TRUE(!mPump, NS_ERROR_IN_PROGRESS); NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED); NS_ENSURE_ARG(listener); // Skip checking for chrome:// sub-resources. nsAutoCString scheme; mURI->GetScheme(scheme); if (!scheme.EqualsLiteral("file")) { NS_CompareLoadInfoAndLoadContext(this); } // Ensure that this is an allowed port before proceeding. nsresult rv = NS_CheckPortSafety(mURI); if (NS_FAILED(rv)) { mCallbacks = nullptr; return rv; } // Store the listener and context early so that OpenContentStream and the // stream's AsyncWait method (called by AsyncRead) can have access to them // via PushStreamConverter and the StreamListener methods. However, since // this typically introduces a reference cycle between this and the listener, // we need to be sure to break the reference if this method does not succeed. mListener = listener; mListenerContext = ctxt; // This method assigns mPump as a side-effect. We need to clear mPump if // this method fails. rv = BeginPumpingData(); if (NS_FAILED(rv)) { mPump = nullptr; ChannelDone(); mCallbacks = nullptr; return rv; } // At this point, we are going to return success no matter what. mWasOpened = true; SUSPEND_PUMP_FOR_SCOPE(); if (mLoadGroup) mLoadGroup->AddRequest(this, nullptr); ClassifyURI(); return NS_OK; }
NS_IMETHODIMP nsBaseChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt) { NS_ENSURE_TRUE(mURI, NS_ERROR_NOT_INITIALIZED); NS_ENSURE_TRUE(!mPump, NS_ERROR_IN_PROGRESS); NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED); NS_ENSURE_ARG(listener); // Ensure that this is an allowed port before proceeding. nsresult rv = NS_CheckPortSafety(mURI); if (NS_FAILED(rv)) { mCallbacks = nullptr; return rv; } // Store the listener and context early so that OpenContentStream and the // stream's AsyncWait method (called by AsyncRead) can have access to them // via PushStreamConverter and the StreamListener methods. However, since // this typically introduces a reference cycle between this and the listener, // we need to be sure to break the reference if this method does not succeed. mListener = listener; mListenerContext = ctxt; // This method assigns mPump as a side-effect. We need to clear mPump if // this method fails. rv = BeginPumpingData(); if (NS_FAILED(rv)) { mPump = nullptr; mListener = nullptr; mListenerContext = nullptr; mCallbacks = nullptr; return rv; } // At this point, we are going to return success no matter what. mWasOpened = true; SUSPEND_PUMP_FOR_SCOPE(); if (mLoadGroup) mLoadGroup->AddRequest(this, nullptr); ClassifyURI(); return NS_OK; }