зеркало из https://github.com/mozilla/pjs.git
fixes bug 293350 "Allow dynamic changes to notification callbacks" r=biesi sr=bzbarsky
This commit is contained in:
Родитель
d5a752d6a5
Коммит
7c7704b82f
|
@ -189,9 +189,6 @@ nsDateTimeChannel::Open(nsIInputStream **_retval)
|
|||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
|
||||
{
|
||||
// Initialize mProgressSink
|
||||
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, mProgressSink);
|
||||
|
||||
nsresult rv = NS_CheckPortSafety(mPort, "datetime");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
@ -327,6 +324,7 @@ NS_IMETHODIMP
|
|||
nsDateTimeChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
|
||||
{
|
||||
mLoadGroup = aLoadGroup;
|
||||
mProgressSink = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -357,6 +355,7 @@ NS_IMETHODIMP
|
|||
nsDateTimeChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
|
||||
{
|
||||
mCallbacks = aNotificationCallbacks;
|
||||
mProgressSink = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -419,6 +418,9 @@ NS_IMETHODIMP
|
|||
nsDateTimeChannel::OnTransportStatus(nsITransport *trans, nsresult status,
|
||||
PRUint64 progress, PRUint64 progressMax)
|
||||
{
|
||||
if (!mProgressSink)
|
||||
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, mProgressSink);
|
||||
|
||||
// suppress status notification if channel is no longer pending!
|
||||
if (mProgressSink && NS_SUCCEEDED(mStatus) && mPump && !(mLoadFlags & LOAD_BACKGROUND)) {
|
||||
NS_ConvertUTF8toUTF16 host(mHost);
|
||||
|
|
|
@ -208,9 +208,6 @@ nsFingerChannel::Open(nsIInputStream **_retval)
|
|||
NS_IMETHODIMP
|
||||
nsFingerChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
|
||||
{
|
||||
// Initialize mProgressSink
|
||||
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, mProgressSink);
|
||||
|
||||
nsresult rv = NS_CheckPortSafety(mPort, "finger");
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
@ -349,6 +346,7 @@ NS_IMETHODIMP
|
|||
nsFingerChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
|
||||
{
|
||||
mLoadGroup = aLoadGroup;
|
||||
mProgressSink = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -379,6 +377,7 @@ NS_IMETHODIMP
|
|||
nsFingerChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
|
||||
{
|
||||
mCallbacks = aNotificationCallbacks;
|
||||
mProgressSink = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -441,6 +440,9 @@ NS_IMETHODIMP
|
|||
nsFingerChannel::OnTransportStatus(nsITransport *trans, nsresult status,
|
||||
PRUint64 progress, PRUint64 progressMax)
|
||||
{
|
||||
if (!mProgressSink)
|
||||
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, mProgressSink);
|
||||
|
||||
// suppress status notification if channel is no longer pending!
|
||||
if (mProgressSink && NS_SUCCEEDED(mStatus) && mPump && !(mLoadFlags & LOAD_BACKGROUND)) {
|
||||
mProgressSink->OnStatus(this, nsnull, status,
|
||||
|
|
|
@ -90,19 +90,20 @@ interface nsIChannel : nsIRequest
|
|||
* The notification callbacks for the channel. This is set by clients, who
|
||||
* wish to provide a means to receive progress, status and protocol-specific
|
||||
* notifications. If this value is NULL, the channel implementation may use
|
||||
* the notification callbacks from its load group.
|
||||
* the notification callbacks from its load group. The channel may also
|
||||
* query the notification callbacks from its load group if its notification
|
||||
* callbacks do not supply the requested interface.
|
||||
*
|
||||
* Interfaces commonly requested include: nsIProgressEventSink, nsIPrompt,
|
||||
* and nsIAuthPrompt.
|
||||
*
|
||||
* NOTE: channels generally query this attribute when they are opened and
|
||||
* retain references to the resulting interfaces until they are done. A
|
||||
* channel may ignore changes to the notificationCallbacks attribute after
|
||||
* it has been opened. This rule also applies to notificationCallbacks
|
||||
* queried from the channel's loadgroup.
|
||||
*
|
||||
* When the channel is done, it must not continue holding references to
|
||||
* this object.
|
||||
*
|
||||
* NOTE: A channel implementation should take care when "caching" an
|
||||
* interface pointer queried from its notification callbacks. If the
|
||||
* notification callbacks are changed, then a cached interface pointer may
|
||||
* become invalid and may therefore need to be re-queried.
|
||||
*/
|
||||
attribute nsIInterfaceRequestor notificationCallbacks;
|
||||
|
||||
|
@ -169,7 +170,9 @@ interface nsIChannel : nsIRequest
|
|||
|
||||
/**
|
||||
* Asynchronously open this channel. Data is fed to the specified stream
|
||||
* listener as it becomes available.
|
||||
* listener as it becomes available. The stream listener's methods are
|
||||
* called on the thread that calls asyncOpen and are not called until
|
||||
* after asyncOpen returns.
|
||||
*
|
||||
* @param aListener the nsIStreamListener implementation
|
||||
* @param aContext an opaque parameter forwarded to aListener's methods
|
||||
|
|
|
@ -163,6 +163,7 @@ NS_IMETHODIMP
|
|||
nsInputStreamChannel::SetLoadGroup(nsILoadGroup *aLoadGroup)
|
||||
{
|
||||
mLoadGroup = aLoadGroup;
|
||||
mProgressSink = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -217,6 +218,7 @@ NS_IMETHODIMP
|
|||
nsInputStreamChannel::SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks)
|
||||
{
|
||||
mCallbacks = aCallbacks;
|
||||
mProgressSink = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -294,9 +296,6 @@ nsInputStreamChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt)
|
|||
NS_ENSURE_TRUE(mContentStream, NS_ERROR_NOT_INITIALIZED);
|
||||
NS_ENSURE_TRUE(!mPump, NS_ERROR_IN_PROGRESS);
|
||||
|
||||
// Initialize mProgressSink
|
||||
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, mProgressSink);
|
||||
|
||||
// if content length is unknown, then we must guess... in this case, we
|
||||
// assume the stream can tell us. if the stream is a pipe, then this will
|
||||
// not work. in that case, we hope that the user of this interface would
|
||||
|
@ -392,6 +391,9 @@ nsInputStreamChannel::OnDataAvailable(nsIRequest *req, nsISupports *ctx,
|
|||
|
||||
rv = mListener->OnDataAvailable(this, mListenerContext, stream, offset, count);
|
||||
|
||||
if (!mProgressSink)
|
||||
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, mProgressSink);
|
||||
|
||||
// XXX need real 64-bit math here! (probably needs new streamlistener and
|
||||
// channel ifaces)
|
||||
if (mProgressSink && NS_SUCCEEDED(rv) && !(mLoadFlags & LOAD_BACKGROUND))
|
||||
|
|
|
@ -214,6 +214,7 @@ NS_IMETHODIMP
|
|||
nsFileChannel::SetLoadGroup(nsILoadGroup *aLoadGroup)
|
||||
{
|
||||
mLoadGroup = aLoadGroup;
|
||||
mProgressSink = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -271,6 +272,7 @@ NS_IMETHODIMP
|
|||
nsFileChannel::SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks)
|
||||
{
|
||||
mCallbacks = aCallbacks;
|
||||
mProgressSink = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -371,9 +373,6 @@ nsFileChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctx)
|
|||
{
|
||||
NS_ENSURE_TRUE(!mRequest, NS_ERROR_IN_PROGRESS);
|
||||
|
||||
// Initialize mProgressSink
|
||||
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, mProgressSink);
|
||||
|
||||
nsCOMPtr<nsIStreamListener> grip;
|
||||
nsCOMPtr<nsIEventQueue> currentEventQ;
|
||||
nsresult rv;
|
||||
|
@ -579,6 +578,9 @@ NS_IMETHODIMP
|
|||
nsFileChannel::OnTransportStatus(nsITransport *trans, nsresult status,
|
||||
PRUint64 progress, PRUint64 progressMax)
|
||||
{
|
||||
if (!mProgressSink)
|
||||
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, mProgressSink);
|
||||
|
||||
// suppress status notification if channel is no longer pending!
|
||||
if (mProgressSink && NS_SUCCEEDED(mStatus) && mRequest && !(mLoadFlags & LOAD_BACKGROUND)) {
|
||||
// file channel does not send OnStatus events!
|
||||
|
|
|
@ -304,20 +304,6 @@ nsFTPChannel::AsyncOpenAt(nsIStreamListener *listener, nsISupports *ctxt,
|
|||
|
||||
PR_LOG(gFTPLog, PR_LOG_DEBUG, ("nsFTPChannel::AsyncOpen() called\n"));
|
||||
|
||||
// Initialize mEventSink
|
||||
//
|
||||
// Build a proxy for the progress event sink since we may need to call it
|
||||
// while we are deep inside some of our state logic, and we wouldn't want
|
||||
// to worry about some weird re-entrancy scenario.
|
||||
nsCOMPtr<nsIProgressEventSink> sink;
|
||||
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, sink);
|
||||
if (sink)
|
||||
NS_GetProxyForObject(NS_CURRENT_EVENTQ,
|
||||
NS_GET_IID(nsIProgressEventSink),
|
||||
sink,
|
||||
PROXY_ASYNC | PROXY_ALWAYS,
|
||||
getter_AddRefs(mEventSink));
|
||||
|
||||
mListener = listener;
|
||||
mUserContext = ctxt;
|
||||
|
||||
|
@ -365,26 +351,47 @@ nsFTPChannel::AsyncOpenAt(nsIStreamListener *listener, nsISupports *ctxt,
|
|||
// XXX this function must not fail since we have already called AddRequest!
|
||||
}
|
||||
|
||||
void
|
||||
nsFTPChannel::GetFTPEventSink(nsCOMPtr<nsIFTPEventSink> &aResult)
|
||||
{
|
||||
if (!mFTPEventSink) {
|
||||
nsCOMPtr<nsIFTPEventSink> ftpSink;
|
||||
GetCallback(ftpSink);
|
||||
if (ftpSink)
|
||||
NS_GetProxyForObject(NS_CURRENT_EVENTQ,
|
||||
NS_GET_IID(nsIFTPEventSink),
|
||||
ftpSink,
|
||||
PROXY_ASYNC | PROXY_ALWAYS,
|
||||
getter_AddRefs(mFTPEventSink));
|
||||
}
|
||||
aResult = mFTPEventSink;
|
||||
}
|
||||
|
||||
void
|
||||
nsFTPChannel::InitProgressSink()
|
||||
{
|
||||
// Build a proxy for the progress event sink since we may need to call it
|
||||
// while we are deep inside some of our state logic, and we wouldn't want
|
||||
// to worry about some weird re-entrancy scenario.
|
||||
nsCOMPtr<nsIProgressEventSink> progressSink;
|
||||
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, progressSink);
|
||||
if (progressSink)
|
||||
NS_GetProxyForObject(NS_CURRENT_EVENTQ,
|
||||
NS_GET_IID(nsIProgressEventSink),
|
||||
progressSink,
|
||||
PROXY_ASYNC | PROXY_ALWAYS,
|
||||
getter_AddRefs(mProgressSink));
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFTPChannel::SetupState(PRUint64 startPos, const nsACString& entityID)
|
||||
{
|
||||
nsCOMPtr<nsIPrompt> prompt;
|
||||
nsCOMPtr<nsIAuthPrompt> authPrompt;
|
||||
nsCOMPtr<nsIFTPEventSink> ftpEventSink;
|
||||
|
||||
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, ftpEventSink);
|
||||
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, prompt);
|
||||
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, authPrompt);
|
||||
|
||||
if (!mFTPState) {
|
||||
NS_NEWXPCOM(mFTPState, nsFtpState);
|
||||
if (!mFTPState) return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(mFTPState);
|
||||
}
|
||||
nsresult rv = mFTPState->Init(this,
|
||||
prompt,
|
||||
authPrompt,
|
||||
ftpEventSink,
|
||||
nsresult rv = mFTPState->Init(this,
|
||||
mCacheEntry,
|
||||
mProxyInfo,
|
||||
startPos,
|
||||
|
@ -478,6 +485,8 @@ NS_IMETHODIMP
|
|||
nsFTPChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
|
||||
{
|
||||
mLoadGroup = aLoadGroup;
|
||||
mProgressSink = nsnull;
|
||||
mFTPEventSink = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -507,6 +516,8 @@ NS_IMETHODIMP
|
|||
nsFTPChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
|
||||
{
|
||||
mCallbacks = aNotificationCallbacks;
|
||||
mProgressSink = nsnull;
|
||||
mFTPEventSink = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -519,7 +530,7 @@ nsFTPChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
|
|||
|
||||
// nsIInterfaceRequestor method
|
||||
NS_IMETHODIMP
|
||||
nsFTPChannel::GetInterface(const nsIID &aIID, void **aResult )
|
||||
nsFTPChannel::GetInterface(const nsIID &aIID, void **aResult)
|
||||
{
|
||||
// capture the progress event sink stuff. pass the rest through.
|
||||
if (aIID.Equals(NS_GET_IID(nsIProgressEventSink))) {
|
||||
|
@ -536,6 +547,9 @@ NS_IMETHODIMP
|
|||
nsFTPChannel::OnStatus(nsIRequest *request, nsISupports *aContext,
|
||||
nsresult aStatus, const PRUnichar* aStatusArg)
|
||||
{
|
||||
if (!mProgressSink)
|
||||
InitProgressSink();
|
||||
|
||||
if (aStatus == NS_NET_STATUS_CONNECTED_TO)
|
||||
{
|
||||
// The state machine needs to know that the data connection
|
||||
|
@ -547,24 +561,27 @@ nsFTPChannel::OnStatus(nsIRequest *request, nsISupports *aContext,
|
|||
NS_ERROR("ftp state is null.");
|
||||
}
|
||||
|
||||
if (!mEventSink || (mLoadFlags & LOAD_BACKGROUND) || !mIsPending || NS_FAILED(mStatus))
|
||||
if (!mProgressSink || (mLoadFlags & LOAD_BACKGROUND) || !mIsPending || NS_FAILED(mStatus))
|
||||
return NS_OK;
|
||||
|
||||
nsCAutoString host;
|
||||
mURL->GetHost(host);
|
||||
return mEventSink->OnStatus(this, mUserContext, aStatus,
|
||||
NS_ConvertUTF8toUTF16(host).get());
|
||||
return mProgressSink->OnStatus(this, mUserContext, aStatus,
|
||||
NS_ConvertUTF8toUTF16(host).get());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFTPChannel::OnProgress(nsIRequest *request, nsISupports* aContext,
|
||||
PRUint64 aProgress, PRUint64 aProgressMax)
|
||||
{
|
||||
if (!mEventSink || (mLoadFlags & LOAD_BACKGROUND) || !mIsPending)
|
||||
if (!mProgressSink)
|
||||
InitProgressSink();
|
||||
|
||||
if (!mProgressSink || (mLoadFlags & LOAD_BACKGROUND) || !mIsPending)
|
||||
return NS_OK;
|
||||
|
||||
return mEventSink->OnProgress(this, mUserContext,
|
||||
aProgress, aProgressMax);
|
||||
return mProgressSink->OnProgress(this, mUserContext,
|
||||
aProgress, aProgressMax);
|
||||
}
|
||||
|
||||
|
||||
|
@ -612,8 +629,9 @@ nsFTPChannel::OnStopRequest(nsIRequest *request, nsISupports* aContext,
|
|||
mIsPending = PR_FALSE;
|
||||
|
||||
// Drop notification callbacks to prevent cycles.
|
||||
mCallbacks = 0;
|
||||
mEventSink = 0;
|
||||
mCallbacks = nsnull;
|
||||
mProgressSink = nsnull;
|
||||
mFTPEventSink = nsnull;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -111,6 +111,18 @@ public:
|
|||
nsresult AsyncOpenAt(nsIStreamListener *listener, nsISupports *ctxt,
|
||||
PRUint64 startPos, const nsACString& entityID);
|
||||
|
||||
// Helper function to simplify getting notification callbacks.
|
||||
template <class T>
|
||||
void GetCallback(nsCOMPtr<T> &aResult) {
|
||||
GetInterface(NS_GET_IID(T), getter_AddRefs(aResult));
|
||||
}
|
||||
|
||||
// Helper function for getting the nsIFTPEventSink.
|
||||
void GetFTPEventSink(nsCOMPtr<nsIFTPEventSink> &aResult);
|
||||
|
||||
protected:
|
||||
void InitProgressSink();
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIURI> mOriginalURI;
|
||||
nsCOMPtr<nsIURI> mURL;
|
||||
|
@ -118,7 +130,8 @@ protected:
|
|||
nsCOMPtr<nsIInputStream> mUploadStream;
|
||||
|
||||
// various callback interfaces
|
||||
nsCOMPtr<nsIProgressEventSink> mEventSink;
|
||||
nsCOMPtr<nsIProgressEventSink> mProgressSink;
|
||||
nsCOMPtr<nsIFTPEventSink> mFTPEventSink;
|
||||
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
|
||||
|
||||
PRBool mIsPending;
|
||||
|
|
|
@ -564,8 +564,10 @@ nsFtpState::OnDataAvailable(nsIRequest *request,
|
|||
mState = mNextState;
|
||||
}
|
||||
|
||||
if (mFTPEventSink)
|
||||
mFTPEventSink->OnFTPControlLog(PR_TRUE, mResponseMsg.get());
|
||||
nsCOMPtr<nsIFTPEventSink> ftpSink;
|
||||
mChannel->GetFTPEventSink(ftpSink);
|
||||
if (ftpSink)
|
||||
ftpSink->OnFTPControlLog(PR_TRUE, mResponseMsg.get());
|
||||
|
||||
rv = Process();
|
||||
mResponseMsg.Truncate();
|
||||
|
@ -1026,7 +1028,11 @@ nsFtpState::S_user() {
|
|||
usernameStr.AppendLiteral("anonymous");
|
||||
} else {
|
||||
if (mUsername.IsEmpty()) {
|
||||
if (!mAuthPrompter) return NS_ERROR_NOT_INITIALIZED;
|
||||
nsCOMPtr<nsIAuthPrompt> prompter;
|
||||
mChannel->GetCallback(prompter);
|
||||
if (!prompter)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
nsXPIDLString user, passwd;
|
||||
PRBool retval;
|
||||
nsCAutoString prePath;
|
||||
|
@ -1046,13 +1052,13 @@ nsFtpState::S_user() {
|
|||
rv = bundle->FormatStringFromName(NS_LITERAL_STRING("EnterUserPasswordFor").get(),
|
||||
formatStrings, 1,
|
||||
getter_Copies(formatedString));
|
||||
rv = mAuthPrompter->PromptUsernameAndPassword(nsnull,
|
||||
formatedString,
|
||||
prePathU.get(),
|
||||
nsIAuthPrompt::SAVE_PASSWORD_PERMANENTLY,
|
||||
getter_Copies(user),
|
||||
getter_Copies(passwd),
|
||||
&retval);
|
||||
rv = prompter->PromptUsernameAndPassword(nsnull,
|
||||
formatedString,
|
||||
prePathU.get(),
|
||||
nsIAuthPrompt::SAVE_PASSWORD_PERMANENTLY,
|
||||
getter_Copies(user),
|
||||
getter_Copies(passwd),
|
||||
&retval);
|
||||
|
||||
// if the user canceled or didn't supply a username we want to fail
|
||||
if (!retval || (user && !*user) )
|
||||
|
@ -1125,7 +1131,10 @@ nsFtpState::S_pass() {
|
|||
}
|
||||
} else {
|
||||
if (mPassword.IsEmpty() || mRetryPass) {
|
||||
if (!mAuthPrompter) return NS_ERROR_NOT_INITIALIZED;
|
||||
nsCOMPtr<nsIAuthPrompt> prompter;
|
||||
mChannel->GetCallback(prompter);
|
||||
if (!prompter)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
nsXPIDLString passwd;
|
||||
PRBool retval;
|
||||
|
@ -1148,11 +1157,11 @@ nsFtpState::S_pass() {
|
|||
getter_Copies(formatedString));
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = mAuthPrompter->PromptPassword(nsnull,
|
||||
formatedString,
|
||||
prePathU.get(),
|
||||
nsIAuthPrompt::SAVE_PASSWORD_PERMANENTLY,
|
||||
getter_Copies(passwd), &retval);
|
||||
rv = prompter->PromptPassword(nsnull,
|
||||
formatedString,
|
||||
prePathU.get(),
|
||||
nsIAuthPrompt::SAVE_PASSWORD_PERMANENTLY,
|
||||
getter_Copies(passwd), &retval);
|
||||
|
||||
// we want to fail if the user canceled. Note here that if they want
|
||||
// a blank password, we will pass it along.
|
||||
|
@ -1297,9 +1306,11 @@ nsFtpState::R_syst() {
|
|||
nsMemory::Free(ucs2Response);
|
||||
if (NS_FAILED(rv)) return FTP_ERROR;
|
||||
|
||||
NS_ASSERTION(mPrompter, "no prompter!");
|
||||
if (mPrompter)
|
||||
(void) mPrompter->Alert(nsnull, formatedString.get());
|
||||
// XXX(darin): this code should not be dictating UI like this!
|
||||
nsCOMPtr<nsIPrompt> prompter;
|
||||
mChannel->GetCallback(prompter);
|
||||
if (prompter)
|
||||
prompter->Alert(nsnull, formatedString.get());
|
||||
|
||||
// since we just alerted the user, clear mResponseMsg,
|
||||
// which is displayed to the user.
|
||||
|
@ -2164,27 +2175,12 @@ nsFtpState::CanReadEntry()
|
|||
|
||||
nsresult
|
||||
nsFtpState::Init(nsFTPChannel* aChannel,
|
||||
nsIPrompt* aPrompter,
|
||||
nsIAuthPrompt* aAuthPrompter,
|
||||
nsIFTPEventSink* sink,
|
||||
nsICacheEntryDescriptor* cacheEntry,
|
||||
nsIProxyInfo* proxyInfo,
|
||||
PRUint64 startPos,
|
||||
const nsACString& entity)
|
||||
{
|
||||
// Build a proxy for the FTP event sink since we may need to call
|
||||
// it while we are deep inside some of our state logic, and we
|
||||
// wouldn't want to worry about some wierd re-entrancy scenario.
|
||||
if (sink)
|
||||
NS_GetProxyForObject(NS_CURRENT_EVENTQ,
|
||||
NS_GET_IID(nsIFTPEventSink),
|
||||
sink,
|
||||
PROXY_ASYNC | PROXY_ALWAYS,
|
||||
getter_AddRefs(mFTPEventSink));
|
||||
|
||||
mKeepRunning = PR_TRUE;
|
||||
mPrompter = aPrompter;
|
||||
mAuthPrompter = aAuthPrompter;
|
||||
mCacheEntry = cacheEntry;
|
||||
mProxyInfo = proxyInfo;
|
||||
mStartPos = startPos;
|
||||
|
@ -2396,14 +2392,16 @@ nsFtpState::StopProcessing()
|
|||
printf("FTP Stopped: [response code %d] [response msg follows:]\n%s\n", mResponseCode, mResponseMsg.get());
|
||||
#endif
|
||||
|
||||
if ( NS_FAILED(mInternalError) && !mResponseMsg.IsEmpty())
|
||||
if (NS_FAILED(mInternalError) && !mResponseMsg.IsEmpty())
|
||||
{
|
||||
// check to see if the control status is bad.
|
||||
// web shell wont throw an alert. we better:
|
||||
|
||||
NS_ASSERTION(mPrompter, "no prompter!");
|
||||
if (mPrompter)
|
||||
(void) mPrompter->Alert(nsnull, NS_ConvertASCIItoUCS2(mResponseMsg).get());
|
||||
|
||||
// XXX(darin): this code should not be dictating UI like this!
|
||||
nsCOMPtr<nsIPrompt> prompter;
|
||||
mChannel->GetCallback(prompter);
|
||||
if (prompter)
|
||||
prompter->Alert(nsnull, NS_ConvertASCIItoUCS2(mResponseMsg).get());
|
||||
}
|
||||
|
||||
nsresult broadcastErrorCode = mControlStatus;
|
||||
|
@ -2445,8 +2443,6 @@ nsFtpState::StopProcessing()
|
|||
// Release the Observers
|
||||
mWriteStream = 0; // should this call close before setting to null?
|
||||
|
||||
mPrompter = 0;
|
||||
mAuthPrompter = 0;
|
||||
mChannel = 0;
|
||||
mProxyInfo = 0;
|
||||
|
||||
|
@ -2519,8 +2515,11 @@ nsFtpState::SendFTPCommand(nsCString& command)
|
|||
logcmd = "PASS xxxxx";
|
||||
|
||||
LOG(("(%x)(dwait=%d) Writing \"%s\"\n", this, mWaitingForDConn, logcmd.get()));
|
||||
if (mFTPEventSink)
|
||||
mFTPEventSink->OnFTPControlLog(PR_FALSE, logcmd.get());
|
||||
|
||||
nsCOMPtr<nsIFTPEventSink> ftpSink;
|
||||
mChannel->GetFTPEventSink(ftpSink);
|
||||
if (ftpSink)
|
||||
ftpSink->OnFTPControlLog(PR_FALSE, logcmd.get());
|
||||
|
||||
if (mControlConnection) {
|
||||
return mControlConnection->Write(command, mWaitingForDConn);
|
||||
|
|
|
@ -119,9 +119,6 @@ public:
|
|||
virtual ~nsFtpState();
|
||||
|
||||
nsresult Init(nsFTPChannel *aChannel,
|
||||
nsIPrompt *aPrompter,
|
||||
nsIAuthPrompt *aAuthPrompter,
|
||||
nsIFTPEventSink *sink,
|
||||
nsICacheEntryDescriptor* cacheEntry,
|
||||
nsIProxyInfo* proxyInfo,
|
||||
PRUint64 startPos,
|
||||
|
@ -229,9 +226,6 @@ private:
|
|||
nsCOMPtr<nsIInputStream> mWriteStream; // This stream is written to the server.
|
||||
PRUint32 mWriteCount;
|
||||
PRPackedBool mIPv6Checked;
|
||||
nsCOMPtr<nsIPrompt> mPrompter;
|
||||
nsCOMPtr<nsIFTPEventSink> mFTPEventSink;
|
||||
nsCOMPtr<nsIAuthPrompt> mAuthPrompter;
|
||||
|
||||
static PRUint32 mSessionStartTime;
|
||||
|
||||
|
|
|
@ -262,9 +262,6 @@ nsGopherChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
|
|||
|
||||
// get callback interfaces...
|
||||
|
||||
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, mPrompter);
|
||||
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, mProgressSink);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
PRInt32 port;
|
||||
|
@ -470,6 +467,7 @@ NS_IMETHODIMP
|
|||
nsGopherChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
|
||||
{
|
||||
mLoadGroup = aLoadGroup;
|
||||
mProgressSink = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -499,6 +497,7 @@ NS_IMETHODIMP
|
|||
nsGopherChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aCallbacks)
|
||||
{
|
||||
mCallbacks = aCallbacks;
|
||||
mProgressSink = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -550,7 +549,6 @@ nsGopherChannel::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
|
|||
|
||||
// Drop notification callbacks to prevent cycles.
|
||||
mCallbacks = 0;
|
||||
mPrompter = 0;
|
||||
mProgressSink = 0;
|
||||
|
||||
return NS_OK;
|
||||
|
@ -593,7 +591,9 @@ nsGopherChannel::SendRequest()
|
|||
if (pos == -1) {
|
||||
// We require a query string here - if we don't have one,
|
||||
// then we need to ask the user
|
||||
if (!mPrompter) {
|
||||
nsCOMPtr<nsIPrompt> prompter;
|
||||
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, prompter);
|
||||
if (!prompter) {
|
||||
NS_ERROR("We need a prompter!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -630,7 +630,7 @@ nsGopherChannel::SendRequest()
|
|||
|
||||
nsXPIDLString search;
|
||||
PRBool res;
|
||||
mPrompter->Prompt(promptTitle.get(),
|
||||
prompter->Prompt(promptTitle.get(),
|
||||
promptText.get(),
|
||||
getter_Copies(search),
|
||||
NULL,
|
||||
|
@ -727,6 +727,9 @@ NS_IMETHODIMP
|
|||
nsGopherChannel::OnTransportStatus(nsITransport *trans, nsresult status,
|
||||
PRUint64 progress, PRUint64 progressMax)
|
||||
{
|
||||
if (!mProgressSink)
|
||||
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, mProgressSink);
|
||||
|
||||
// suppress status notification if channel is no longer pending!
|
||||
if (mProgressSink && NS_SUCCEEDED(mStatus) && mPump && !(mLoadFlags & LOAD_BACKGROUND)) {
|
||||
NS_ConvertUTF8toUTF16 host(mHost);
|
||||
|
|
|
@ -81,7 +81,6 @@ public:
|
|||
protected:
|
||||
nsCOMPtr<nsIURI> mOriginalURI;
|
||||
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
|
||||
nsCOMPtr<nsIPrompt> mPrompter;
|
||||
nsCOMPtr<nsIProgressEventSink> mProgressSink;
|
||||
nsCOMPtr<nsIURI> mUrl;
|
||||
nsCOMPtr<nsIStreamListener> mListener;
|
||||
|
|
|
@ -2059,19 +2059,23 @@ nsHttpChannel::ProcessRedirection(PRUint32 redirectType)
|
|||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// call out to the event sink to notify it of this redirection.
|
||||
if (mHttpEventSink) {
|
||||
// Note: mHttpEventSink is only kept for compatibility with pre-1.8
|
||||
nsCOMPtr<nsIHttpEventSink> httpEventSink;
|
||||
GetCallback(httpEventSink);
|
||||
if (httpEventSink) {
|
||||
// NOTE: nsIHttpEventSink is only used for compatibility with pre-1.8
|
||||
// versions.
|
||||
rv = mHttpEventSink->OnRedirect(this, newChannel);
|
||||
rv = httpEventSink->OnRedirect(this, newChannel);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
if (mChannelEventSink) {
|
||||
nsCOMPtr<nsIChannelEventSink> channelEventSink;
|
||||
GetCallback(channelEventSink);
|
||||
if (channelEventSink) {
|
||||
PRUint32 flags;
|
||||
if (redirectType == 301) // Moved Permanently
|
||||
flags = nsIChannelEventSink::REDIRECT_PERMANENT;
|
||||
else
|
||||
flags = nsIChannelEventSink::REDIRECT_TEMPORARY;
|
||||
rv = mChannelEventSink->OnChannelRedirect(this, newChannel, flags);
|
||||
rv = channelEventSink->OnChannelRedirect(this, newChannel, flags);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
// XXX we used to talk directly with the script security manager, but that
|
||||
|
@ -3100,6 +3104,7 @@ NS_IMETHODIMP
|
|||
nsHttpChannel::SetLoadGroup(nsILoadGroup *aLoadGroup)
|
||||
{
|
||||
mLoadGroup = aLoadGroup;
|
||||
mProgressSink = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -3176,6 +3181,7 @@ NS_IMETHODIMP
|
|||
nsHttpChannel::SetNotificationCallbacks(nsIInterfaceRequestor *callbacks)
|
||||
{
|
||||
mCallbacks = callbacks;
|
||||
mProgressSink = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -3294,11 +3300,6 @@ nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context)
|
|||
|
||||
nsresult rv;
|
||||
|
||||
// Initialize callback interfaces
|
||||
GetCallback(mHttpEventSink);
|
||||
GetCallback(mChannelEventSink);
|
||||
GetCallback(mProgressSink);
|
||||
|
||||
// we want to grab a reference to the calling thread's event queue at
|
||||
// this point. we will proxy all events back to the current thread via
|
||||
// this event queue.
|
||||
|
@ -4093,8 +4094,6 @@ nsHttpChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult st
|
|||
mLoadGroup->RemoveRequest(this, nsnull, status);
|
||||
|
||||
mCallbacks = nsnull;
|
||||
mHttpEventSink = nsnull;
|
||||
mChannelEventSink = nsnull;
|
||||
mProgressSink = nsnull;
|
||||
mEventQ = nsnull;
|
||||
|
||||
|
@ -4177,6 +4176,10 @@ NS_IMETHODIMP
|
|||
nsHttpChannel::OnTransportStatus(nsITransport *trans, nsresult status,
|
||||
PRUint64 progress, PRUint64 progressMax)
|
||||
{
|
||||
// cache the progress sink so we don't have to query for it each time.
|
||||
if (!mProgressSink)
|
||||
GetCallback(mProgressSink);
|
||||
|
||||
// block socket status event after Cancel or OnStopRequest has been called.
|
||||
if (mProgressSink && NS_SUCCEEDED(mStatus) && mIsPending && !(mLoadFlags & LOAD_BACKGROUND)) {
|
||||
LOG(("sending status notification [this=%x status=%x progress=%llu/%llu]\n",
|
||||
|
|
|
@ -218,8 +218,6 @@ private:
|
|||
nsCOMPtr<nsISupports> mOwner;
|
||||
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
|
||||
nsCOMPtr<nsIProgressEventSink> mProgressSink;
|
||||
nsCOMPtr<nsIHttpEventSink> mHttpEventSink;
|
||||
nsCOMPtr<nsIChannelEventSink> mChannelEventSink;
|
||||
nsCOMPtr<nsIInputStream> mUploadStream;
|
||||
nsCOMPtr<nsIURI> mReferrer;
|
||||
nsCOMPtr<nsISupports> mSecurityInfo;
|
||||
|
|
Загрузка…
Ссылка в новой задаче