diff --git a/netwerk/protocol/ftp/FTPChannelChild.cpp b/netwerk/protocol/ftp/FTPChannelChild.cpp index b83a695a4395..a50a09462b0c 100644 --- a/netwerk/protocol/ftp/FTPChannelChild.cpp +++ b/netwerk/protocol/ftp/FTPChannelChild.cpp @@ -18,6 +18,7 @@ #include "mozilla/ipc/URIUtils.h" #include "SerializedLoadContext.h" #include "mozilla/ipc/BackgroundUtils.h" +#include "nsIPrompt.h" using namespace mozilla::ipc; @@ -471,23 +472,31 @@ class FTPStopRequestEvent : public ChannelEvent { public: FTPStopRequestEvent(FTPChannelChild* aChild, - const nsresult& aChannelStatus) + const nsresult& aChannelStatus, + const nsCString &aErrorMsg, + bool aUseUTF8) : mChild(aChild) , mChannelStatus(aChannelStatus) + , mErrorMsg(aErrorMsg) + , mUseUTF8(aUseUTF8) { } void Run() { - mChild->DoOnStopRequest(mChannelStatus); + mChild->DoOnStopRequest(mChannelStatus, mErrorMsg, mUseUTF8); } private: FTPChannelChild* mChild; nsresult mChannelStatus; + nsCString mErrorMsg; + bool mUseUTF8; }; bool -FTPChannelChild::RecvOnStopRequest(const nsresult& aChannelStatus) +FTPChannelChild::RecvOnStopRequest(const nsresult& aChannelStatus, + const nsCString &aErrorMsg, + const bool &aUseUTF8) { MOZ_RELEASE_ASSERT(!mFlushedForDiversion, "Should not be receiving any more callbacks from parent!"); @@ -495,10 +504,38 @@ FTPChannelChild::RecvOnStopRequest(const nsresult& aChannelStatus) LOG(("FTPChannelChild::RecvOnStopRequest [this=%p status=%x]\n", this, aChannelStatus)); - mEventQ->RunOrEnqueue(new FTPStopRequestEvent(this, aChannelStatus)); + mEventQ->RunOrEnqueue(new FTPStopRequestEvent(this, aChannelStatus, aErrorMsg, + aUseUTF8)); return true; } +class nsFtpChildAsyncAlert : public Runnable +{ +public: + nsFtpChildAsyncAlert(nsIPrompt *aPrompter, nsString aResponseMsg) + : mPrompter(aPrompter) + , mResponseMsg(aResponseMsg) + { + MOZ_COUNT_CTOR(nsFtpChildAsyncAlert); + } +protected: + virtual ~nsFtpChildAsyncAlert() + { + MOZ_COUNT_DTOR(nsFtpChildAsyncAlert); + } +public: + NS_IMETHOD Run() + { + if (mPrompter) { + mPrompter->Alert(nullptr, mResponseMsg.get()); + } + return NS_OK; + } +private: + nsCOMPtr mPrompter; + nsString mResponseMsg; +}; + class MaybeDivertOnStopFTPEvent : public ChannelEvent { public: @@ -526,7 +563,9 @@ FTPChannelChild::MaybeDivertOnStop(const nsresult& aChannelStatus) } void -FTPChannelChild::DoOnStopRequest(const nsresult& aChannelStatus) +FTPChannelChild::DoOnStopRequest(const nsresult& aChannelStatus, + const nsCString &aErrorMsg, + bool aUseUTF8) { LOG(("FTPChannelChild::DoOnStopRequest [this=%p status=%x]\n", this, aChannelStatus)); @@ -552,6 +591,23 @@ FTPChannelChild::DoOnStopRequest(const nsresult& aChannelStatus) mIsPending = false; AutoEventEnqueuer ensureSerialDispatch(mEventQ); (void)mListener->OnStopRequest(this, mListenerContext, aChannelStatus); + + if (NS_FAILED(aChannelStatus) && !aErrorMsg.IsEmpty()) { + nsCOMPtr prompter; + GetCallback(prompter); + if (prompter) { + nsCOMPtr alertEvent; + if (aUseUTF8) { + alertEvent = new nsFtpChildAsyncAlert(prompter, + NS_ConvertUTF8toUTF16(aErrorMsg)); + } else { + alertEvent = new nsFtpChildAsyncAlert(prompter, + NS_ConvertASCIItoUTF16(aErrorMsg)); + } + NS_DispatchToMainThread(alertEvent); + } + } + mListener = nullptr; mListenerContext = nullptr; diff --git a/netwerk/protocol/ftp/FTPChannelChild.h b/netwerk/protocol/ftp/FTPChannelChild.h index de2155d81931..f68b85a72d45 100644 --- a/netwerk/protocol/ftp/FTPChannelChild.h +++ b/netwerk/protocol/ftp/FTPChannelChild.h @@ -86,7 +86,9 @@ protected: const nsCString& data, const uint64_t& offset, const uint32_t& count) override; - bool RecvOnStopRequest(const nsresult& channelStatus) override; + bool RecvOnStopRequest(const nsresult& channelStatus, + const nsCString &aErrorMsg, + const bool &aUseUTF8) override; bool RecvFailedAsyncOpen(const nsresult& statusCode) override; bool RecvFlushedForDiversion() override; bool RecvDivertMessages() override; @@ -106,7 +108,9 @@ protected: const uint64_t& offset, const uint32_t& count); void MaybeDivertOnStop(const nsresult& statusCode); - void DoOnStopRequest(const nsresult& statusCode); + void DoOnStopRequest(const nsresult& statusCode, + const nsCString &aErrorMsg, + bool aUseUTF8); void DoFailedAsyncOpen(const nsresult& statusCode); void DoDeleteSelf(); diff --git a/netwerk/protocol/ftp/FTPChannelParent.cpp b/netwerk/protocol/ftp/FTPChannelParent.cpp index fbe3addde21b..1b768195639b 100644 --- a/netwerk/protocol/ftp/FTPChannelParent.cpp +++ b/netwerk/protocol/ftp/FTPChannelParent.cpp @@ -47,6 +47,7 @@ FTPChannelParent::FTPChannelParent(const PBrowserOrId& aIframeEmbedding, , mDivertingFromChild(false) , mDivertedOnStartRequest(false) , mSuspendedForDiversion(false) + , mUseUTF8(false) { nsIProtocolHandler* handler; CallGetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "ftp", &handler); @@ -86,7 +87,8 @@ NS_IMPL_ISUPPORTS(FTPChannelParent, nsIParentChannel, nsIInterfaceRequestor, nsIRequestObserver, - nsIChannelEventSink) + nsIChannelEventSink, + nsIFTPChannelParentInternal) //----------------------------------------------------------------------------- // FTPChannelParent::PFTPChannelParent @@ -516,7 +518,7 @@ FTPChannelParent::OnStopRequest(nsIRequest* aRequest, return mDivertToListener->OnStopRequest(aRequest, aContext, aStatusCode); } - if (mIPCClosed || !SendOnStopRequest(aStatusCode)) { + if (mIPCClosed || !SendOnStopRequest(aStatusCode, mErrorMsg, mUseUTF8)) { return NS_ERROR_UNEXPECTED; } @@ -910,6 +912,14 @@ FTPChannelParent::AsyncOnChannelRedirect( return NS_OK; } +NS_IMETHODIMP +FTPChannelParent::SetErrorMsg(const char *aMsg, bool aUseUTF8) +{ + mErrorMsg = aMsg; + mUseUTF8 = aUseUTF8; + return NS_OK; +} + //--------------------- } // namespace net } // namespace mozilla diff --git a/netwerk/protocol/ftp/FTPChannelParent.h b/netwerk/protocol/ftp/FTPChannelParent.h index 96b290b651f1..f003be99d53d 100644 --- a/netwerk/protocol/ftp/FTPChannelParent.h +++ b/netwerk/protocol/ftp/FTPChannelParent.h @@ -15,6 +15,7 @@ #include "nsIInterfaceRequestor.h" #include "OfflineObserver.h" #include "nsIChannelEventSink.h" +#include "nsIFTPChannelParentInternal.h" class nsILoadContext; @@ -34,6 +35,7 @@ class FTPChannelParent final : public PFTPChannelParent , public ADivertableParentChannel , public nsIChannelEventSink , public DisconnectableParent + , public nsIFTPChannelParentInternal { public: NS_DECL_ISUPPORTS @@ -64,6 +66,8 @@ public: // Called asynchronously from FailDiversion. void NotifyDiversionFailed(nsresult aErrorCode, bool aSkipResume = true); + NS_IMETHOD SetErrorMsg(const char *aMsg, bool aUseUTF8) override; + protected: virtual ~FTPChannelParent(); @@ -137,6 +141,9 @@ protected: RefPtr mTabParent; RefPtr mEventQ; + + nsCString mErrorMsg; + bool mUseUTF8; }; } // namespace net diff --git a/netwerk/protocol/ftp/PFTPChannel.ipdl b/netwerk/protocol/ftp/PFTPChannel.ipdl index 9793074f6d51..55721bdbeae8 100644 --- a/netwerk/protocol/ftp/PFTPChannel.ipdl +++ b/netwerk/protocol/ftp/PFTPChannel.ipdl @@ -54,7 +54,9 @@ child: nsCString data, uint64_t offset, uint32_t count); - async OnStopRequest(nsresult channelStatus); + async OnStopRequest(nsresult channelStatus, + nsCString aErrorMsg, + bool aUseUTF8); async FailedAsyncOpen(nsresult statusCode); // Parent has been suspended for diversion; no more events to be enqueued. diff --git a/netwerk/protocol/ftp/moz.build b/netwerk/protocol/ftp/moz.build index d39417e11067..776f00243412 100644 --- a/netwerk/protocol/ftp/moz.build +++ b/netwerk/protocol/ftp/moz.build @@ -6,6 +6,7 @@ XPIDL_SOURCES += [ 'nsIFTPChannel.idl', + 'nsIFTPChannelParentInternal.idl', ] XPIDL_MODULE = 'necko_ftp' diff --git a/netwerk/protocol/ftp/nsFtpConnectionThread.cpp b/netwerk/protocol/ftp/nsFtpConnectionThread.cpp index 48f4b8971afd..1956006abfbb 100644 --- a/netwerk/protocol/ftp/nsFtpConnectionThread.cpp +++ b/netwerk/protocol/ftp/nsFtpConnectionThread.cpp @@ -43,6 +43,7 @@ #include "nsILoadInfo.h" #include "nsNullPrincipal.h" #include "nsIAuthPrompt2.h" +#include "nsIFTPChannelParentInternal.h" #ifdef MOZ_WIDGET_GONK #include "NetStatistics.h" @@ -1849,6 +1850,11 @@ nsFtpState::StopProcessing() } NS_DispatchToMainThread(alertEvent); } + nsCOMPtr ftpChanP; + mChannel->GetCallback(ftpChanP); + if (ftpChanP) { + ftpChanP->SetErrorMsg(mResponseMsg.get(), mUseUTF8); + } } nsresult broadcastErrorCode = mControlStatus; diff --git a/netwerk/protocol/ftp/nsIFTPChannelParentInternal.idl b/netwerk/protocol/ftp/nsIFTPChannelParentInternal.idl new file mode 100644 index 000000000000..2642c804b1e9 --- /dev/null +++ b/netwerk/protocol/ftp/nsIFTPChannelParentInternal.idl @@ -0,0 +1,15 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" + +/** + * This is an internal interface for FTP parent channel. + */ +[builtinclass, uuid(87b58410-83cb-42a7-b57b-27c07ef828d7)] +interface nsIFTPChannelParentInternal : nsISupports +{ + void setErrorMsg(in string msg, in boolean useUTF8); +};