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 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; }