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 FTPChannelChild::AsyncOpen(::nsIStreamListener* listener, nsISupports* aContext) { LOG(("FTPChannelChild::AsyncOpen [this=%x]\n", this)); NS_ENSURE_TRUE((gNeckoChild), NS_ERROR_FAILURE); NS_ENSURE_ARG_POINTER(listener); NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS); NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED); // Port checked in parent, but duplicate here so we can return with error // immediately, as we've done since before e10s. nsresult rv; rv = NS_CheckPortSafety(nsBaseChannel::URI()); // Need to disambiguate, // because in the child ipdl, // a typedef URI is defined... if (NS_FAILED(rv)) return rv; // FIXME: like bug 558623, merge constructor+SendAsyncOpen into 1 IPC msg gNeckoChild->SendPFTPChannelConstructor(this); mListener = listener; mListenerContext = aContext; // add ourselves to the load group. if (mLoadGroup) mLoadGroup->AddRequest(this, nsnull); // Get info from nsILoadContext, if any bool haveLoadContext = false; bool isContent = false; bool usePrivateBrowsing = false; bool isInBrowserElement = false; PRUint32 appId = 0; nsCOMPtr<nsILoadContext> loadContext; NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, NS_GET_IID(nsILoadContext), getter_AddRefs(loadContext)); if (loadContext) { haveLoadContext = true; loadContext->GetIsContent(&isContent); loadContext->GetUsePrivateBrowsing(&usePrivateBrowsing); loadContext->GetIsInBrowserElement(&isInBrowserElement); loadContext->GetAppId(&appId); } SendAsyncOpen(nsBaseChannel::URI(), mStartPos, mEntityID, IPC::InputStream(mUploadStream), haveLoadContext, isContent, usePrivateBrowsing, isInBrowserElement, appId); // The socket transport layer in the chrome process now has a logical ref to // us until OnStopRequest is called. AddIPDLReference(); mIsPending = true; mWasOpened = true; return rv; }
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; }
NS_IMETHODIMP FTPChannelChild::AsyncOpen(::nsIStreamListener* listener, nsISupports* aContext) { LOG(("FTPChannelChild::AsyncOpen [this=%x]\n", this)); NS_ENSURE_TRUE((gNeckoChild), NS_ERROR_FAILURE); NS_ENSURE_ARG_POINTER(listener); NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS); NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED); // Port checked in parent, but duplicate here so we can return with error // immediately, as we've done since before e10s. nsresult rv; rv = NS_CheckPortSafety(nsBaseChannel::URI()); // Need to disambiguate, // because in the child ipdl, // a typedef URI is defined... if (NS_FAILED(rv)) return rv; // FIXME: like bug 558623, merge constructor+SendAsyncOpen into 1 IPC msg gNeckoChild->SendPFTPChannelConstructor(this); mListener = listener; mListenerContext = aContext; // add ourselves to the load group. if (mLoadGroup) mLoadGroup->AddRequest(this, nsnull); SendAsyncOpen(nsBaseChannel::URI(), mStartPos, mEntityID, IPC::InputStream(mUploadStream)); // The socket transport layer in the chrome process now has a logical ref to // us until OnStopRequest is called. AddIPDLReference(); mIsPending = PR_TRUE; mWasOpened = PR_TRUE; return rv; }
NS_IMETHODIMP HttpChannelChild::AsyncOpen(nsIStreamListener *listener, nsISupports *aContext) { LOG(("HttpChannelChild::AsyncOpen [this=%x uri=%s]\n", this, mSpec.get())); if (mCanceled) return mStatus; NS_ENSURE_TRUE(gNeckoChild != nsnull, NS_ERROR_FAILURE); NS_ENSURE_ARG_POINTER(listener); NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS); NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED); // Port checked in parent, but duplicate here so we can return with error // immediately nsresult rv; rv = NS_CheckPortSafety(mURI); if (NS_FAILED(rv)) return rv; const char *cookieHeader = mRequestHead.PeekHeader(nsHttp::Cookie); if (cookieHeader) { mUserSetCookieHeader = cookieHeader; } AddCookiesToRequest(); // // NOTE: From now on we must return NS_OK; all errors must be handled via // OnStart/OnStopRequest // // notify "http-on-modify-request" observers gHttpHandler->OnModifyRequest(this); mIsPending = true; mWasOpened = true; mListener = listener; mListenerContext = aContext; // add ourselves to the load group. if (mLoadGroup) mLoadGroup->AddRequest(this, nsnull); if (mCanceled) { // We may have been canceled already, either by on-modify-request // listeners or by load group observers; in that case, don't create IPDL // connection. See nsHttpChannel::AsyncOpen(). AsyncAbort(mStatus); return NS_OK; } nsCString appCacheClientId; if (mInheritApplicationCache) { // Pick up an application cache from the notification // callbacks if available nsCOMPtr<nsIApplicationCacheContainer> appCacheContainer; GetCallback(appCacheContainer); if (appCacheContainer) { nsCOMPtr<nsIApplicationCache> appCache; rv = appCacheContainer->GetApplicationCache(getter_AddRefs(appCache)); if (NS_SUCCEEDED(rv) && appCache) { appCache->GetClientID(appCacheClientId); } } } // // Send request to the chrome process... // // FIXME: bug 558623: Combine constructor and SendAsyncOpen into one IPC msg mozilla::dom::TabChild* tabChild = nsnull; nsCOMPtr<nsITabChild> iTabChild; GetCallback(iTabChild); if (iTabChild) { tabChild = static_cast<mozilla::dom::TabChild*>(iTabChild.get()); } // The socket transport in the chrome process now holds a logical ref to us // until OnStopRequest, or we do a redirect, or we hit an IPDL error. AddIPDLReference(); gNeckoChild->SendPHttpChannelConstructor(this, tabChild); SendAsyncOpen(IPC::URI(mURI), IPC::URI(mOriginalURI), IPC::URI(mDocumentURI), IPC::URI(mReferrer), mLoadFlags, mClientSetRequestHeaders, mRequestHead.Method(), IPC::InputStream(mUploadStream), mUploadStreamHasHeaders, mPriority, mRedirectionLimit, mAllowPipelining, mForceAllowThirdPartyCookie, mSendResumeAt, mStartPos, mEntityID, mChooseApplicationCache, appCacheClientId, mAllowSpdy, UsePrivateBrowsing()); return NS_OK; }
NS_IMETHODIMP nsGopherChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt) { PR_LOG(gGopherLog, PR_LOG_DEBUG, ("nsGopherChannel::AsyncOpen() called [this=%x]\n", this)); // get callback interfaces... nsresult rv; PRInt32 port; rv = mUrl->GetPort(&port); if (NS_FAILED(rv)) return rv; rv = NS_CheckPortSafety(port, "gopher"); if (NS_FAILED(rv)) return rv; // push stream converters in front of the consumer... nsCOMPtr<nsIStreamListener> converter; rv = PushStreamConverters(aListener, getter_AddRefs(converter)); if (NS_FAILED(rv)) return rv; // create socket transport nsCOMPtr<nsISocketTransportService> socketService = do_GetService(kSocketTransportServiceCID, &rv); if (NS_FAILED(rv)) return rv; rv = socketService->CreateTransport(nsnull, 0, mHost, mPort, mProxyInfo, getter_AddRefs(mTransport)); if (NS_FAILED(rv)) return rv; // setup notification callbacks... if (!(mLoadFlags & LOAD_BACKGROUND)) { nsCOMPtr<nsIEventQueue> eventQ; NS_GetCurrentEventQ(getter_AddRefs(eventQ)); if (eventQ) mTransport->SetEventSink(this, eventQ); } // open buffered, asynchronous socket input stream, and use a input stream // pump to read from it. nsCOMPtr<nsIInputStream> input; rv = mTransport->OpenInputStream(0, 0, 0, getter_AddRefs(input)); if (NS_FAILED(rv)) return rv; rv = SendRequest(); if (NS_FAILED(rv)) return rv; rv = NS_NewInputStreamPump(getter_AddRefs(mPump), input); if (NS_FAILED(rv)) return rv; rv = mPump->AsyncRead(this, nsnull); if (NS_FAILED(rv)) return rv; if (mLoadGroup) mLoadGroup->AddRequest(this, nsnull); mIsPending = PR_TRUE; if (converter) mListener = converter; else mListener = aListener; mListenerContext = ctxt; return NS_OK; }
NS_IMETHODIMP HttpChannelChild::AsyncOpen(nsIStreamListener *listener, nsISupports *aContext) { LOG(("HttpChannelChild::AsyncOpen [this=%x uri=%s]\n", this, mSpec.get())); if (mCanceled) return mStatus; NS_ENSURE_TRUE(gNeckoChild != nsnull, NS_ERROR_FAILURE); NS_ENSURE_ARG_POINTER(listener); NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS); NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED); // Port checked in parent, but duplicate here so we can return with error // immediately nsresult rv; rv = NS_CheckPortSafety(mURI); if (NS_FAILED(rv)) return rv; // Prepare uploadStream for POST data nsCAutoString uploadStreamData; PRInt32 uploadStreamInfo; if (mUploadStream) { // Read entire POST stream into string: // This is a temporary measure until bug 564553 is implemented: we're doing // a blocking read of a potentially arbitrarily large stream, so this isn't // performant/safe for large file uploads. PRUint32 bytes; mUploadStream->Available(&bytes); if (bytes > 0) { rv = NS_ReadInputStreamToString(mUploadStream, uploadStreamData, bytes); if (NS_FAILED(rv)) return rv; } uploadStreamInfo = mUploadStreamHasHeaders ? eUploadStream_hasHeaders : eUploadStream_hasNoHeaders; } else { uploadStreamInfo = eUploadStream_null; } const char *cookieHeader = mRequestHead.PeekHeader(nsHttp::Cookie); if (cookieHeader) { mUserSetCookieHeader = cookieHeader; } AddCookiesToRequest(); // // NOTE: From now on we must return NS_OK; all errors must be handled via // OnStart/OnStopRequest // // notify "http-on-modify-request" observers gHttpHandler->OnModifyRequest(this); mIsPending = PR_TRUE; mWasOpened = PR_TRUE; mListener = listener; mListenerContext = aContext; // add ourselves to the load group. if (mLoadGroup) mLoadGroup->AddRequest(this, nsnull); if (mCanceled) { // We may have been canceled already, either by on-modify-request // listeners or by load group observers; in that case, don't create IPDL // connection. See nsHttpChannel::AsyncOpen(). // Clear mCanceled here, or we will bail out at top of OnCancel(). mCanceled = false; OnCancel(mStatus); return NS_OK; } // // Send request to the chrome process... // // FIXME: bug 558623: Combine constructor and SendAsyncOpen into one IPC msg mozilla::dom::TabChild* tabChild = nsnull; nsCOMPtr<nsITabChild> iTabChild; GetCallback(iTabChild); if (iTabChild) { tabChild = static_cast<mozilla::dom::TabChild*>(iTabChild.get()); } // The socket transport in the chrome process now holds a logical ref to us // until OnStopRequest, or we do a redirect, or we hit an IPDL error. AddIPDLReference(); gNeckoChild->SendPHttpChannelConstructor(this, tabChild); SendAsyncOpen(IPC::URI(mURI), IPC::URI(mOriginalURI), IPC::URI(mDocumentURI), IPC::URI(mReferrer), mLoadFlags, mRequestHeaders, mRequestHead.Method(), uploadStreamData, uploadStreamInfo, mPriority, mRedirectionLimit, mAllowPipelining, mForceAllowThirdPartyCookie, mSendResumeAt, mStartPos, mEntityID); return NS_OK; }
NS_IMETHODIMP nsFingerChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt) { nsresult rv = NS_CheckPortSafety(mPort, "finger"); if (NS_FAILED(rv)) return rv; nsCOMPtr<nsIThread> thread = do_GetCurrentThread(); NS_ENSURE_STATE(thread); // // create transport // nsCOMPtr<nsISocketTransportService> sts = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; rv = sts->CreateTransport(nsnull, 0, mHost, mPort, mProxyInfo, getter_AddRefs(mTransport)); if (NS_FAILED(rv)) return rv; // not fatal if this fails mTransport->SetEventSink(this, thread); rv = WriteRequest(mTransport); if (NS_FAILED(rv)) return rv; // // create TXT to HTML stream converter // nsCOMPtr<nsIStreamConverterService> scs = do_GetService(NS_STREAMCONVERTERSERVICE_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; nsCOMPtr<nsIStreamListener> convListener; rv = scs->AsyncConvertData("text/plain", "text/html", this, nsnull, getter_AddRefs(convListener)); if (NS_FAILED(rv)) return rv; nsCOMPtr<nsITXTToHTMLConv> conv = do_QueryInterface(convListener); if (conv) { nsCAutoString userHost; rv = mURI->GetPath(userHost); nsAutoString title; title.AppendLiteral("Finger information for "); AppendUTF8toUTF16(userHost, title); conv->SetTitle(title.get()); conv->PreFormatHTML(PR_TRUE); } // // open input stream, and create input stream pump... // nsCOMPtr<nsIInputStream> sockIn; rv = mTransport->OpenInputStream(0, 0, 0, getter_AddRefs(sockIn)); if (NS_FAILED(rv)) return rv; rv = NS_NewInputStreamPump(getter_AddRefs(mPump), sockIn); if (NS_FAILED(rv)) return rv; rv = mPump->AsyncRead(convListener, nsnull); if (NS_FAILED(rv)) return rv; if (mLoadGroup) mLoadGroup->AddRequest(this, nsnull); mListener = aListener; mListenerContext = ctxt; return NS_OK; }
NS_IMETHODIMP nsLDAPChannel::AsyncOpen(nsIStreamListener* aListener, nsISupports* aCtxt) { nsresult rv; nsCAutoString host; // slurp out relevant pieces of the URL // rv = mURI->GetAsciiHost(host); if (NS_FAILED(rv)) { NS_ERROR("nsLDAPChannel::AsyncRead(): mURI->GetAsciiHost failed\n"); return NS_ERROR_FAILURE; } // we don't currently allow for a default host // if (host.IsEmpty()) return NS_ERROR_MALFORMED_URI; // QI to nsILDAPURL so that we can call one of the methods on that iface // nsCOMPtr<nsILDAPURL> mLDAPURL = do_QueryInterface(mURI, &rv); if (NS_FAILED(rv)) { NS_ERROR("nsLDAPChannel::AsyncRead(): QI to nsILDAPURL failed\n"); return NS_ERROR_FAILURE; } rv = NS_CheckPortSafety(mURI); if (NS_FAILED(rv)) return rv; // save off the args // mResponseContext = aCtxt; mUnproxiedListener = aListener; // add ourselves to the appropriate loadgroup // if (mLoadGroup) { mLoadGroup->AddRequest(this, mResponseContext); } // since the LDAP SDK does all the socket management, we don't have // an underlying transport channel to create an nsIInputStream to hand // back to the nsIStreamListener. So we do it ourselves: // if (!mReadPipeIn) { // get a new pipe, propagating any error upwards // rv = NS_NewPipe(getter_AddRefs(mReadPipeIn), getter_AddRefs(mReadPipeOut), 0, 0, PR_TRUE, PR_FALSE, 0); if (NS_FAILED(rv)) { NS_ERROR("nsLDAPChannel::AsyncRead(): unable to create new pipe"); return NS_ERROR_FAILURE; } } // get an AsyncStreamListener to proxy for mListener, if we're // compiled to have the LDAP callbacks happen on the LDAP connection= // thread. // #if INVOKE_LDAP_CALLBACKS_ON_MAIN_THREAD mListener = aListener; #else rv = NS_GetProxyForObject(NS_PROXY_TO_MAIN_THREAD, NS_GET_IID(nsIStreamListener), mUnproxiedListener, NS_PROXY_ASYNC | NS_PROXY_ALWAYS, getter_AddRefs(mListener)); if (NS_FAILED(rv)) { NS_ERROR("nsLDAPChannel::AsyncRead(): unable to create new " "AsyncStreamListener"); return NS_ERROR_FAILURE; } #endif // we already know the content type, so we can fire this now // mUnproxiedListener->OnStartRequest(this, mResponseContext); if (NS_FAILED(rv)) { NS_ERROR("nsLDAPChannel::AsyncRead(): error firing OnStartRequest"); return NS_ERROR_FAILURE; } // initialize it with the defaults // XXXdmose - need to deal with bind name // Need to deal with VERSION2 pref - don't know how to get it from here. rv = mConnection->Init(mLDAPURL, EmptyCString(), this, nsnull, nsILDAPConnection::VERSION3); switch (rv) { case NS_OK: break; case NS_ERROR_OUT_OF_MEMORY: case NS_ERROR_NOT_AVAILABLE: case NS_ERROR_FAILURE: return rv; case NS_ERROR_ILLEGAL_VALUE: default: return NS_ERROR_UNEXPECTED; } // create and initialize an LDAP operation (to be used for the bind) // mCurrentOperation = do_CreateInstance( "@mozilla.org/network/ldap-operation;1", &rv); if (NS_FAILED(rv)) { return NS_ERROR_FAILURE; } // our OnLDAPMessage accepts all result callbacks // rv = mCurrentOperation->Init(mConnection, mCallback, nsnull); if (NS_FAILED(rv)) return NS_ERROR_UNEXPECTED; // this should never happen // kick off a bind operation // PR_LOG(gLDAPLogModule, PR_LOG_DEBUG, ("initiating SimpleBind\n")); rv = mCurrentOperation->SimpleBind(EmptyCString()); if (NS_FAILED(rv)) { // XXXdmose better error handling / passthrough; deal with password // NS_WARNING("mCurrentOperation->SimpleBind failed."); return(rv); } return NS_OK; }