fixes bug 293350 "Allow dynamic changes to notification callbacks" r=biesi sr=bzbarsky

This commit is contained in:
darin%meer.net 2005-09-10 00:20:02 +00:00
Родитель d5a752d6a5
Коммит 7c7704b82f
13 изменённых файлов: 164 добавлений и 126 удалений

Просмотреть файл

@ -189,9 +189,6 @@ nsDateTimeChannel::Open(nsIInputStream **_retval)
NS_IMETHODIMP NS_IMETHODIMP
nsDateTimeChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt) nsDateTimeChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
{ {
// Initialize mProgressSink
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, mProgressSink);
nsresult rv = NS_CheckPortSafety(mPort, "datetime"); nsresult rv = NS_CheckPortSafety(mPort, "datetime");
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
@ -327,6 +324,7 @@ NS_IMETHODIMP
nsDateTimeChannel::SetLoadGroup(nsILoadGroup* aLoadGroup) nsDateTimeChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
{ {
mLoadGroup = aLoadGroup; mLoadGroup = aLoadGroup;
mProgressSink = nsnull;
return NS_OK; return NS_OK;
} }
@ -357,6 +355,7 @@ NS_IMETHODIMP
nsDateTimeChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks) nsDateTimeChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
{ {
mCallbacks = aNotificationCallbacks; mCallbacks = aNotificationCallbacks;
mProgressSink = nsnull;
return NS_OK; return NS_OK;
} }
@ -419,6 +418,9 @@ NS_IMETHODIMP
nsDateTimeChannel::OnTransportStatus(nsITransport *trans, nsresult status, nsDateTimeChannel::OnTransportStatus(nsITransport *trans, nsresult status,
PRUint64 progress, PRUint64 progressMax) PRUint64 progress, PRUint64 progressMax)
{ {
if (!mProgressSink)
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, mProgressSink);
// suppress status notification if channel is no longer pending! // suppress status notification if channel is no longer pending!
if (mProgressSink && NS_SUCCEEDED(mStatus) && mPump && !(mLoadFlags & LOAD_BACKGROUND)) { if (mProgressSink && NS_SUCCEEDED(mStatus) && mPump && !(mLoadFlags & LOAD_BACKGROUND)) {
NS_ConvertUTF8toUTF16 host(mHost); NS_ConvertUTF8toUTF16 host(mHost);

Просмотреть файл

@ -208,9 +208,6 @@ nsFingerChannel::Open(nsIInputStream **_retval)
NS_IMETHODIMP NS_IMETHODIMP
nsFingerChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt) nsFingerChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
{ {
// Initialize mProgressSink
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, mProgressSink);
nsresult rv = NS_CheckPortSafety(mPort, "finger"); nsresult rv = NS_CheckPortSafety(mPort, "finger");
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
@ -349,6 +346,7 @@ NS_IMETHODIMP
nsFingerChannel::SetLoadGroup(nsILoadGroup* aLoadGroup) nsFingerChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
{ {
mLoadGroup = aLoadGroup; mLoadGroup = aLoadGroup;
mProgressSink = nsnull;
return NS_OK; return NS_OK;
} }
@ -379,6 +377,7 @@ NS_IMETHODIMP
nsFingerChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks) nsFingerChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
{ {
mCallbacks = aNotificationCallbacks; mCallbacks = aNotificationCallbacks;
mProgressSink = nsnull;
return NS_OK; return NS_OK;
} }
@ -441,6 +440,9 @@ NS_IMETHODIMP
nsFingerChannel::OnTransportStatus(nsITransport *trans, nsresult status, nsFingerChannel::OnTransportStatus(nsITransport *trans, nsresult status,
PRUint64 progress, PRUint64 progressMax) PRUint64 progress, PRUint64 progressMax)
{ {
if (!mProgressSink)
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, mProgressSink);
// suppress status notification if channel is no longer pending! // suppress status notification if channel is no longer pending!
if (mProgressSink && NS_SUCCEEDED(mStatus) && mPump && !(mLoadFlags & LOAD_BACKGROUND)) { if (mProgressSink && NS_SUCCEEDED(mStatus) && mPump && !(mLoadFlags & LOAD_BACKGROUND)) {
mProgressSink->OnStatus(this, nsnull, status, mProgressSink->OnStatus(this, nsnull, status,

Просмотреть файл

@ -90,19 +90,20 @@ interface nsIChannel : nsIRequest
* The notification callbacks for the channel. This is set by clients, who * The notification callbacks for the channel. This is set by clients, who
* wish to provide a means to receive progress, status and protocol-specific * wish to provide a means to receive progress, status and protocol-specific
* notifications. If this value is NULL, the channel implementation may use * 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, * Interfaces commonly requested include: nsIProgressEventSink, nsIPrompt,
* and nsIAuthPrompt. * 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 * When the channel is done, it must not continue holding references to
* this object. * 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; attribute nsIInterfaceRequestor notificationCallbacks;
@ -169,7 +170,9 @@ interface nsIChannel : nsIRequest
/** /**
* Asynchronously open this channel. Data is fed to the specified stream * 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 aListener the nsIStreamListener implementation
* @param aContext an opaque parameter forwarded to aListener's methods * @param aContext an opaque parameter forwarded to aListener's methods

Просмотреть файл

@ -163,6 +163,7 @@ NS_IMETHODIMP
nsInputStreamChannel::SetLoadGroup(nsILoadGroup *aLoadGroup) nsInputStreamChannel::SetLoadGroup(nsILoadGroup *aLoadGroup)
{ {
mLoadGroup = aLoadGroup; mLoadGroup = aLoadGroup;
mProgressSink = nsnull;
return NS_OK; return NS_OK;
} }
@ -217,6 +218,7 @@ NS_IMETHODIMP
nsInputStreamChannel::SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks) nsInputStreamChannel::SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks)
{ {
mCallbacks = aCallbacks; mCallbacks = aCallbacks;
mProgressSink = nsnull;
return NS_OK; return NS_OK;
} }
@ -294,9 +296,6 @@ nsInputStreamChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt)
NS_ENSURE_TRUE(mContentStream, NS_ERROR_NOT_INITIALIZED); NS_ENSURE_TRUE(mContentStream, NS_ERROR_NOT_INITIALIZED);
NS_ENSURE_TRUE(!mPump, NS_ERROR_IN_PROGRESS); 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 // 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 // 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 // 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); 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 // XXX need real 64-bit math here! (probably needs new streamlistener and
// channel ifaces) // channel ifaces)
if (mProgressSink && NS_SUCCEEDED(rv) && !(mLoadFlags & LOAD_BACKGROUND)) if (mProgressSink && NS_SUCCEEDED(rv) && !(mLoadFlags & LOAD_BACKGROUND))

Просмотреть файл

@ -214,6 +214,7 @@ NS_IMETHODIMP
nsFileChannel::SetLoadGroup(nsILoadGroup *aLoadGroup) nsFileChannel::SetLoadGroup(nsILoadGroup *aLoadGroup)
{ {
mLoadGroup = aLoadGroup; mLoadGroup = aLoadGroup;
mProgressSink = nsnull;
return NS_OK; return NS_OK;
} }
@ -271,6 +272,7 @@ NS_IMETHODIMP
nsFileChannel::SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks) nsFileChannel::SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks)
{ {
mCallbacks = aCallbacks; mCallbacks = aCallbacks;
mProgressSink = nsnull;
return NS_OK; return NS_OK;
} }
@ -371,9 +373,6 @@ nsFileChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctx)
{ {
NS_ENSURE_TRUE(!mRequest, NS_ERROR_IN_PROGRESS); NS_ENSURE_TRUE(!mRequest, NS_ERROR_IN_PROGRESS);
// Initialize mProgressSink
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, mProgressSink);
nsCOMPtr<nsIStreamListener> grip; nsCOMPtr<nsIStreamListener> grip;
nsCOMPtr<nsIEventQueue> currentEventQ; nsCOMPtr<nsIEventQueue> currentEventQ;
nsresult rv; nsresult rv;
@ -579,6 +578,9 @@ NS_IMETHODIMP
nsFileChannel::OnTransportStatus(nsITransport *trans, nsresult status, nsFileChannel::OnTransportStatus(nsITransport *trans, nsresult status,
PRUint64 progress, PRUint64 progressMax) PRUint64 progress, PRUint64 progressMax)
{ {
if (!mProgressSink)
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, mProgressSink);
// suppress status notification if channel is no longer pending! // suppress status notification if channel is no longer pending!
if (mProgressSink && NS_SUCCEEDED(mStatus) && mRequest && !(mLoadFlags & LOAD_BACKGROUND)) { if (mProgressSink && NS_SUCCEEDED(mStatus) && mRequest && !(mLoadFlags & LOAD_BACKGROUND)) {
// file channel does not send OnStatus events! // 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")); 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; mListener = listener;
mUserContext = ctxt; mUserContext = ctxt;
@ -365,26 +351,47 @@ nsFTPChannel::AsyncOpenAt(nsIStreamListener *listener, nsISupports *ctxt,
// XXX this function must not fail since we have already called AddRequest! // 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 nsresult
nsFTPChannel::SetupState(PRUint64 startPos, const nsACString& entityID) 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) { if (!mFTPState) {
NS_NEWXPCOM(mFTPState, nsFtpState); NS_NEWXPCOM(mFTPState, nsFtpState);
if (!mFTPState) return NS_ERROR_OUT_OF_MEMORY; if (!mFTPState) return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(mFTPState); NS_ADDREF(mFTPState);
} }
nsresult rv = mFTPState->Init(this, nsresult rv = mFTPState->Init(this,
prompt,
authPrompt,
ftpEventSink,
mCacheEntry, mCacheEntry,
mProxyInfo, mProxyInfo,
startPos, startPos,
@ -478,6 +485,8 @@ NS_IMETHODIMP
nsFTPChannel::SetLoadGroup(nsILoadGroup* aLoadGroup) nsFTPChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
{ {
mLoadGroup = aLoadGroup; mLoadGroup = aLoadGroup;
mProgressSink = nsnull;
mFTPEventSink = nsnull;
return NS_OK; return NS_OK;
} }
@ -507,6 +516,8 @@ NS_IMETHODIMP
nsFTPChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks) nsFTPChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
{ {
mCallbacks = aNotificationCallbacks; mCallbacks = aNotificationCallbacks;
mProgressSink = nsnull;
mFTPEventSink = nsnull;
return NS_OK; return NS_OK;
} }
@ -519,7 +530,7 @@ nsFTPChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
// nsIInterfaceRequestor method // nsIInterfaceRequestor method
NS_IMETHODIMP 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. // capture the progress event sink stuff. pass the rest through.
if (aIID.Equals(NS_GET_IID(nsIProgressEventSink))) { if (aIID.Equals(NS_GET_IID(nsIProgressEventSink))) {
@ -536,6 +547,9 @@ NS_IMETHODIMP
nsFTPChannel::OnStatus(nsIRequest *request, nsISupports *aContext, nsFTPChannel::OnStatus(nsIRequest *request, nsISupports *aContext,
nsresult aStatus, const PRUnichar* aStatusArg) nsresult aStatus, const PRUnichar* aStatusArg)
{ {
if (!mProgressSink)
InitProgressSink();
if (aStatus == NS_NET_STATUS_CONNECTED_TO) if (aStatus == NS_NET_STATUS_CONNECTED_TO)
{ {
// The state machine needs to know that the data connection // 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."); 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; return NS_OK;
nsCAutoString host; nsCAutoString host;
mURL->GetHost(host); mURL->GetHost(host);
return mEventSink->OnStatus(this, mUserContext, aStatus, return mProgressSink->OnStatus(this, mUserContext, aStatus,
NS_ConvertUTF8toUTF16(host).get()); NS_ConvertUTF8toUTF16(host).get());
} }
NS_IMETHODIMP NS_IMETHODIMP
nsFTPChannel::OnProgress(nsIRequest *request, nsISupports* aContext, nsFTPChannel::OnProgress(nsIRequest *request, nsISupports* aContext,
PRUint64 aProgress, PRUint64 aProgressMax) PRUint64 aProgress, PRUint64 aProgressMax)
{ {
if (!mEventSink || (mLoadFlags & LOAD_BACKGROUND) || !mIsPending) if (!mProgressSink)
InitProgressSink();
if (!mProgressSink || (mLoadFlags & LOAD_BACKGROUND) || !mIsPending)
return NS_OK; return NS_OK;
return mEventSink->OnProgress(this, mUserContext, return mProgressSink->OnProgress(this, mUserContext,
aProgress, aProgressMax); aProgress, aProgressMax);
} }
@ -612,8 +629,9 @@ nsFTPChannel::OnStopRequest(nsIRequest *request, nsISupports* aContext,
mIsPending = PR_FALSE; mIsPending = PR_FALSE;
// Drop notification callbacks to prevent cycles. // Drop notification callbacks to prevent cycles.
mCallbacks = 0; mCallbacks = nsnull;
mEventSink = 0; mProgressSink = nsnull;
mFTPEventSink = nsnull;
return rv; return rv;
} }

Просмотреть файл

@ -111,6 +111,18 @@ public:
nsresult AsyncOpenAt(nsIStreamListener *listener, nsISupports *ctxt, nsresult AsyncOpenAt(nsIStreamListener *listener, nsISupports *ctxt,
PRUint64 startPos, const nsACString& entityID); 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: protected:
nsCOMPtr<nsIURI> mOriginalURI; nsCOMPtr<nsIURI> mOriginalURI;
nsCOMPtr<nsIURI> mURL; nsCOMPtr<nsIURI> mURL;
@ -118,7 +130,8 @@ protected:
nsCOMPtr<nsIInputStream> mUploadStream; nsCOMPtr<nsIInputStream> mUploadStream;
// various callback interfaces // various callback interfaces
nsCOMPtr<nsIProgressEventSink> mEventSink; nsCOMPtr<nsIProgressEventSink> mProgressSink;
nsCOMPtr<nsIFTPEventSink> mFTPEventSink;
nsCOMPtr<nsIInterfaceRequestor> mCallbacks; nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
PRBool mIsPending; PRBool mIsPending;

Просмотреть файл

@ -564,8 +564,10 @@ nsFtpState::OnDataAvailable(nsIRequest *request,
mState = mNextState; mState = mNextState;
} }
if (mFTPEventSink) nsCOMPtr<nsIFTPEventSink> ftpSink;
mFTPEventSink->OnFTPControlLog(PR_TRUE, mResponseMsg.get()); mChannel->GetFTPEventSink(ftpSink);
if (ftpSink)
ftpSink->OnFTPControlLog(PR_TRUE, mResponseMsg.get());
rv = Process(); rv = Process();
mResponseMsg.Truncate(); mResponseMsg.Truncate();
@ -1026,7 +1028,11 @@ nsFtpState::S_user() {
usernameStr.AppendLiteral("anonymous"); usernameStr.AppendLiteral("anonymous");
} else { } else {
if (mUsername.IsEmpty()) { 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; nsXPIDLString user, passwd;
PRBool retval; PRBool retval;
nsCAutoString prePath; nsCAutoString prePath;
@ -1046,13 +1052,13 @@ nsFtpState::S_user() {
rv = bundle->FormatStringFromName(NS_LITERAL_STRING("EnterUserPasswordFor").get(), rv = bundle->FormatStringFromName(NS_LITERAL_STRING("EnterUserPasswordFor").get(),
formatStrings, 1, formatStrings, 1,
getter_Copies(formatedString)); getter_Copies(formatedString));
rv = mAuthPrompter->PromptUsernameAndPassword(nsnull, rv = prompter->PromptUsernameAndPassword(nsnull,
formatedString, formatedString,
prePathU.get(), prePathU.get(),
nsIAuthPrompt::SAVE_PASSWORD_PERMANENTLY, nsIAuthPrompt::SAVE_PASSWORD_PERMANENTLY,
getter_Copies(user), getter_Copies(user),
getter_Copies(passwd), getter_Copies(passwd),
&retval); &retval);
// if the user canceled or didn't supply a username we want to fail // if the user canceled or didn't supply a username we want to fail
if (!retval || (user && !*user) ) if (!retval || (user && !*user) )
@ -1125,7 +1131,10 @@ nsFtpState::S_pass() {
} }
} else { } else {
if (mPassword.IsEmpty() || mRetryPass) { 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; nsXPIDLString passwd;
PRBool retval; PRBool retval;
@ -1148,11 +1157,11 @@ nsFtpState::S_pass() {
getter_Copies(formatedString)); getter_Copies(formatedString));
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
rv = mAuthPrompter->PromptPassword(nsnull, rv = prompter->PromptPassword(nsnull,
formatedString, formatedString,
prePathU.get(), prePathU.get(),
nsIAuthPrompt::SAVE_PASSWORD_PERMANENTLY, nsIAuthPrompt::SAVE_PASSWORD_PERMANENTLY,
getter_Copies(passwd), &retval); getter_Copies(passwd), &retval);
// we want to fail if the user canceled. Note here that if they want // we want to fail if the user canceled. Note here that if they want
// a blank password, we will pass it along. // a blank password, we will pass it along.
@ -1297,9 +1306,11 @@ nsFtpState::R_syst() {
nsMemory::Free(ucs2Response); nsMemory::Free(ucs2Response);
if (NS_FAILED(rv)) return FTP_ERROR; if (NS_FAILED(rv)) return FTP_ERROR;
NS_ASSERTION(mPrompter, "no prompter!"); // XXX(darin): this code should not be dictating UI like this!
if (mPrompter) nsCOMPtr<nsIPrompt> prompter;
(void) mPrompter->Alert(nsnull, formatedString.get()); mChannel->GetCallback(prompter);
if (prompter)
prompter->Alert(nsnull, formatedString.get());
// since we just alerted the user, clear mResponseMsg, // since we just alerted the user, clear mResponseMsg,
// which is displayed to the user. // which is displayed to the user.
@ -2164,27 +2175,12 @@ nsFtpState::CanReadEntry()
nsresult nsresult
nsFtpState::Init(nsFTPChannel* aChannel, nsFtpState::Init(nsFTPChannel* aChannel,
nsIPrompt* aPrompter,
nsIAuthPrompt* aAuthPrompter,
nsIFTPEventSink* sink,
nsICacheEntryDescriptor* cacheEntry, nsICacheEntryDescriptor* cacheEntry,
nsIProxyInfo* proxyInfo, nsIProxyInfo* proxyInfo,
PRUint64 startPos, PRUint64 startPos,
const nsACString& entity) 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; mKeepRunning = PR_TRUE;
mPrompter = aPrompter;
mAuthPrompter = aAuthPrompter;
mCacheEntry = cacheEntry; mCacheEntry = cacheEntry;
mProxyInfo = proxyInfo; mProxyInfo = proxyInfo;
mStartPos = startPos; mStartPos = startPos;
@ -2396,14 +2392,16 @@ nsFtpState::StopProcessing()
printf("FTP Stopped: [response code %d] [response msg follows:]\n%s\n", mResponseCode, mResponseMsg.get()); printf("FTP Stopped: [response code %d] [response msg follows:]\n%s\n", mResponseCode, mResponseMsg.get());
#endif #endif
if ( NS_FAILED(mInternalError) && !mResponseMsg.IsEmpty()) if (NS_FAILED(mInternalError) && !mResponseMsg.IsEmpty())
{ {
// check to see if the control status is bad. // check to see if the control status is bad.
// web shell wont throw an alert. we better: // web shell wont throw an alert. we better:
NS_ASSERTION(mPrompter, "no prompter!"); // XXX(darin): this code should not be dictating UI like this!
if (mPrompter) nsCOMPtr<nsIPrompt> prompter;
(void) mPrompter->Alert(nsnull, NS_ConvertASCIItoUCS2(mResponseMsg).get()); mChannel->GetCallback(prompter);
if (prompter)
prompter->Alert(nsnull, NS_ConvertASCIItoUCS2(mResponseMsg).get());
} }
nsresult broadcastErrorCode = mControlStatus; nsresult broadcastErrorCode = mControlStatus;
@ -2445,8 +2443,6 @@ nsFtpState::StopProcessing()
// Release the Observers // Release the Observers
mWriteStream = 0; // should this call close before setting to null? mWriteStream = 0; // should this call close before setting to null?
mPrompter = 0;
mAuthPrompter = 0;
mChannel = 0; mChannel = 0;
mProxyInfo = 0; mProxyInfo = 0;
@ -2519,8 +2515,11 @@ nsFtpState::SendFTPCommand(nsCString& command)
logcmd = "PASS xxxxx"; logcmd = "PASS xxxxx";
LOG(("(%x)(dwait=%d) Writing \"%s\"\n", this, mWaitingForDConn, logcmd.get())); 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) { if (mControlConnection) {
return mControlConnection->Write(command, mWaitingForDConn); return mControlConnection->Write(command, mWaitingForDConn);

Просмотреть файл

@ -119,9 +119,6 @@ public:
virtual ~nsFtpState(); virtual ~nsFtpState();
nsresult Init(nsFTPChannel *aChannel, nsresult Init(nsFTPChannel *aChannel,
nsIPrompt *aPrompter,
nsIAuthPrompt *aAuthPrompter,
nsIFTPEventSink *sink,
nsICacheEntryDescriptor* cacheEntry, nsICacheEntryDescriptor* cacheEntry,
nsIProxyInfo* proxyInfo, nsIProxyInfo* proxyInfo,
PRUint64 startPos, PRUint64 startPos,
@ -229,9 +226,6 @@ private:
nsCOMPtr<nsIInputStream> mWriteStream; // This stream is written to the server. nsCOMPtr<nsIInputStream> mWriteStream; // This stream is written to the server.
PRUint32 mWriteCount; PRUint32 mWriteCount;
PRPackedBool mIPv6Checked; PRPackedBool mIPv6Checked;
nsCOMPtr<nsIPrompt> mPrompter;
nsCOMPtr<nsIFTPEventSink> mFTPEventSink;
nsCOMPtr<nsIAuthPrompt> mAuthPrompter;
static PRUint32 mSessionStartTime; static PRUint32 mSessionStartTime;

Просмотреть файл

@ -262,9 +262,6 @@ nsGopherChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
// get callback interfaces... // get callback interfaces...
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, mPrompter);
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, mProgressSink);
nsresult rv; nsresult rv;
PRInt32 port; PRInt32 port;
@ -470,6 +467,7 @@ NS_IMETHODIMP
nsGopherChannel::SetLoadGroup(nsILoadGroup* aLoadGroup) nsGopherChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
{ {
mLoadGroup = aLoadGroup; mLoadGroup = aLoadGroup;
mProgressSink = nsnull;
return NS_OK; return NS_OK;
} }
@ -499,6 +497,7 @@ NS_IMETHODIMP
nsGopherChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aCallbacks) nsGopherChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aCallbacks)
{ {
mCallbacks = aCallbacks; mCallbacks = aCallbacks;
mProgressSink = nsnull;
return NS_OK; return NS_OK;
} }
@ -550,7 +549,6 @@ nsGopherChannel::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
// Drop notification callbacks to prevent cycles. // Drop notification callbacks to prevent cycles.
mCallbacks = 0; mCallbacks = 0;
mPrompter = 0;
mProgressSink = 0; mProgressSink = 0;
return NS_OK; return NS_OK;
@ -593,7 +591,9 @@ nsGopherChannel::SendRequest()
if (pos == -1) { if (pos == -1) {
// We require a query string here - if we don't have one, // We require a query string here - if we don't have one,
// then we need to ask the user // 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!"); NS_ERROR("We need a prompter!");
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
@ -630,7 +630,7 @@ nsGopherChannel::SendRequest()
nsXPIDLString search; nsXPIDLString search;
PRBool res; PRBool res;
mPrompter->Prompt(promptTitle.get(), prompter->Prompt(promptTitle.get(),
promptText.get(), promptText.get(),
getter_Copies(search), getter_Copies(search),
NULL, NULL,
@ -727,6 +727,9 @@ NS_IMETHODIMP
nsGopherChannel::OnTransportStatus(nsITransport *trans, nsresult status, nsGopherChannel::OnTransportStatus(nsITransport *trans, nsresult status,
PRUint64 progress, PRUint64 progressMax) PRUint64 progress, PRUint64 progressMax)
{ {
if (!mProgressSink)
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, mProgressSink);
// suppress status notification if channel is no longer pending! // suppress status notification if channel is no longer pending!
if (mProgressSink && NS_SUCCEEDED(mStatus) && mPump && !(mLoadFlags & LOAD_BACKGROUND)) { if (mProgressSink && NS_SUCCEEDED(mStatus) && mPump && !(mLoadFlags & LOAD_BACKGROUND)) {
NS_ConvertUTF8toUTF16 host(mHost); NS_ConvertUTF8toUTF16 host(mHost);

Просмотреть файл

@ -81,7 +81,6 @@ public:
protected: protected:
nsCOMPtr<nsIURI> mOriginalURI; nsCOMPtr<nsIURI> mOriginalURI;
nsCOMPtr<nsIInterfaceRequestor> mCallbacks; nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsIPrompt> mPrompter;
nsCOMPtr<nsIProgressEventSink> mProgressSink; nsCOMPtr<nsIProgressEventSink> mProgressSink;
nsCOMPtr<nsIURI> mUrl; nsCOMPtr<nsIURI> mUrl;
nsCOMPtr<nsIStreamListener> mListener; nsCOMPtr<nsIStreamListener> mListener;

Просмотреть файл

@ -2059,19 +2059,23 @@ nsHttpChannel::ProcessRedirection(PRUint32 redirectType)
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
// call out to the event sink to notify it of this redirection. // call out to the event sink to notify it of this redirection.
if (mHttpEventSink) { nsCOMPtr<nsIHttpEventSink> httpEventSink;
// Note: mHttpEventSink is only kept for compatibility with pre-1.8 GetCallback(httpEventSink);
if (httpEventSink) {
// NOTE: nsIHttpEventSink is only used for compatibility with pre-1.8
// versions. // versions.
rv = mHttpEventSink->OnRedirect(this, newChannel); rv = httpEventSink->OnRedirect(this, newChannel);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
} }
if (mChannelEventSink) { nsCOMPtr<nsIChannelEventSink> channelEventSink;
GetCallback(channelEventSink);
if (channelEventSink) {
PRUint32 flags; PRUint32 flags;
if (redirectType == 301) // Moved Permanently if (redirectType == 301) // Moved Permanently
flags = nsIChannelEventSink::REDIRECT_PERMANENT; flags = nsIChannelEventSink::REDIRECT_PERMANENT;
else else
flags = nsIChannelEventSink::REDIRECT_TEMPORARY; flags = nsIChannelEventSink::REDIRECT_TEMPORARY;
rv = mChannelEventSink->OnChannelRedirect(this, newChannel, flags); rv = channelEventSink->OnChannelRedirect(this, newChannel, flags);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
} }
// XXX we used to talk directly with the script security manager, but that // XXX we used to talk directly with the script security manager, but that
@ -3100,6 +3104,7 @@ NS_IMETHODIMP
nsHttpChannel::SetLoadGroup(nsILoadGroup *aLoadGroup) nsHttpChannel::SetLoadGroup(nsILoadGroup *aLoadGroup)
{ {
mLoadGroup = aLoadGroup; mLoadGroup = aLoadGroup;
mProgressSink = nsnull;
return NS_OK; return NS_OK;
} }
@ -3176,6 +3181,7 @@ NS_IMETHODIMP
nsHttpChannel::SetNotificationCallbacks(nsIInterfaceRequestor *callbacks) nsHttpChannel::SetNotificationCallbacks(nsIInterfaceRequestor *callbacks)
{ {
mCallbacks = callbacks; mCallbacks = callbacks;
mProgressSink = nsnull;
return NS_OK; return NS_OK;
} }
@ -3294,11 +3300,6 @@ nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context)
nsresult rv; 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 // 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 point. we will proxy all events back to the current thread via
// this event queue. // this event queue.
@ -4093,8 +4094,6 @@ nsHttpChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult st
mLoadGroup->RemoveRequest(this, nsnull, status); mLoadGroup->RemoveRequest(this, nsnull, status);
mCallbacks = nsnull; mCallbacks = nsnull;
mHttpEventSink = nsnull;
mChannelEventSink = nsnull;
mProgressSink = nsnull; mProgressSink = nsnull;
mEventQ = nsnull; mEventQ = nsnull;
@ -4177,6 +4176,10 @@ NS_IMETHODIMP
nsHttpChannel::OnTransportStatus(nsITransport *trans, nsresult status, nsHttpChannel::OnTransportStatus(nsITransport *trans, nsresult status,
PRUint64 progress, PRUint64 progressMax) 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. // block socket status event after Cancel or OnStopRequest has been called.
if (mProgressSink && NS_SUCCEEDED(mStatus) && mIsPending && !(mLoadFlags & LOAD_BACKGROUND)) { if (mProgressSink && NS_SUCCEEDED(mStatus) && mIsPending && !(mLoadFlags & LOAD_BACKGROUND)) {
LOG(("sending status notification [this=%x status=%x progress=%llu/%llu]\n", LOG(("sending status notification [this=%x status=%x progress=%llu/%llu]\n",

Просмотреть файл

@ -218,8 +218,6 @@ private:
nsCOMPtr<nsISupports> mOwner; nsCOMPtr<nsISupports> mOwner;
nsCOMPtr<nsIInterfaceRequestor> mCallbacks; nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsIProgressEventSink> mProgressSink; nsCOMPtr<nsIProgressEventSink> mProgressSink;
nsCOMPtr<nsIHttpEventSink> mHttpEventSink;
nsCOMPtr<nsIChannelEventSink> mChannelEventSink;
nsCOMPtr<nsIInputStream> mUploadStream; nsCOMPtr<nsIInputStream> mUploadStream;
nsCOMPtr<nsIURI> mReferrer; nsCOMPtr<nsIURI> mReferrer;
nsCOMPtr<nsISupports> mSecurityInfo; nsCOMPtr<nsISupports> mSecurityInfo;