diff options
Diffstat (limited to 'mailnews/base/util/nsMsgProtocol.h')
-rw-r--r-- | mailnews/base/util/nsMsgProtocol.h | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/mailnews/base/util/nsMsgProtocol.h b/mailnews/base/util/nsMsgProtocol.h new file mode 100644 index 000000000..98aa67285 --- /dev/null +++ b/mailnews/base/util/nsMsgProtocol.h @@ -0,0 +1,239 @@ +/* -*- 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/. */ + +#ifndef nsMsgProtocol_h__ +#define nsMsgProtocol_h__ + +#include "mozilla/Attributes.h" +#include "nsIStreamListener.h" +#include "nsIInputStream.h" +#include "nsIOutputStream.h" +#include "nsIChannel.h" +#include "nsIURL.h" +#include "nsIThread.h" +#include "nsILoadGroup.h" +#include "nsIFile.h" +#include "nsCOMPtr.h" +#include "nsIInterfaceRequestor.h" +#include "nsIInterfaceRequestorUtils.h" +#include "nsIProgressEventSink.h" +#include "nsITransport.h" +#include "nsIAsyncOutputStream.h" +#include "nsIAuthModule.h" +#include "nsStringGlue.h" +#include "nsWeakReference.h" + +class nsIMsgWindow; +class nsIPrompt; +class nsIMsgMailNewsUrl; +class nsMsgFilePostHelper; +class nsIProxyInfo; + +#undef IMETHOD_VISIBILITY +#define IMETHOD_VISIBILITY NS_VISIBILITY_DEFAULT + +// This is a helper class used to encapsulate code shared between all of the +// mailnews protocol objects (imap, news, pop, smtp, etc.) In particular, +// it unifies the core networking code for the protocols. My hope is that +// this will make unification with Necko easier as we'll only have to change +// this class and not all of the mailnews protocols. +class NS_MSG_BASE nsMsgProtocol : public nsIStreamListener + , public nsIChannel + , public nsITransportEventSink +{ +public: + nsMsgProtocol(nsIURI * aURL); + + NS_DECL_THREADSAFE_ISUPPORTS + // nsIChannel support + NS_DECL_NSICHANNEL + NS_DECL_NSIREQUEST + + NS_DECL_NSISTREAMLISTENER + NS_DECL_NSIREQUESTOBSERVER + NS_DECL_NSITRANSPORTEVENTSINK + + // LoadUrl -- A protocol typically overrides this function, sets up any local state for the url and + // then calls the base class which opens the socket if it needs opened. If the socket is + // already opened then we just call ProcessProtocolState to start the churning process. + // aConsumer is the consumer for the url. It can be null if this argument is not appropriate + virtual nsresult LoadUrl(nsIURI * aURL, nsISupports * aConsumer = nullptr); + + virtual nsresult SetUrl(nsIURI * aURL); // sometimes we want to set the url before we load it + void ShowAlertMessage(nsIMsgMailNewsUrl *aMsgUrl, nsresult aStatus); + + // Flag manipulators + virtual bool TestFlag (uint32_t flag) {return flag & m_flags;} + virtual void SetFlag (uint32_t flag) { m_flags |= flag; } + virtual void ClearFlag (uint32_t flag) { m_flags &= ~flag; } + +protected: + virtual ~nsMsgProtocol(); + + // methods for opening and closing a socket with core netlib.... + // mscott -okay this is lame. I should break this up into a file protocol and a socket based + // protocool class instead of cheating and putting both methods here... + + // open a connection with a specific host and port + // aHostName must be UTF-8 encoded. + virtual nsresult OpenNetworkSocketWithInfo(const char * aHostName, + int32_t aGetPort, + const char *connectionType, + nsIProxyInfo *aProxyInfo, + nsIInterfaceRequestor* callbacks); + // helper routine + nsresult GetFileFromURL(nsIURI * aURL, nsIFile **aResult); + virtual nsresult OpenFileSocket(nsIURI * aURL, uint32_t aStartPosition, int32_t aReadCount); // used to open a file socket connection + + nsresult GetTopmostMsgWindow(nsIMsgWindow **aWindow); + + virtual const char* GetType() {return nullptr;} + nsresult GetQoSBits(uint8_t *aQoSBits); + + // a Protocol typically overrides this method. They free any of their own connection state and then + // they call up into the base class to free the generic connection objects + virtual nsresult CloseSocket(); + + virtual nsresult SetupTransportState(); // private method used by OpenNetworkSocket and OpenFileSocket + + // ProcessProtocolState - This is the function that gets churned by calls to OnDataAvailable. + // As data arrives on the socket, OnDataAvailable calls ProcessProtocolState. + + virtual nsresult ProcessProtocolState(nsIURI * url, nsIInputStream * inputStream, + uint64_t sourceOffset, uint32_t length) = 0; + + // SendData -- Writes the data contained in dataBuffer into the current output stream. + // It also informs the transport layer that this data is now available for transmission. + // Returns a positive number for success, 0 for failure (not all the bytes were written to the + // stream, etc). + // aSuppressLogging is a hint that sensitive data is being sent and should not be logged + virtual nsresult SendData(const char * dataBuffer, bool aSuppressLogging = false); + + virtual nsresult PostMessage(nsIURI* url, nsIFile* aPostFile); + + virtual nsresult InitFromURI(nsIURI *aUrl); + + nsresult DoNtlmStep1(const char *username, const char *password, nsCString &response); + nsresult DoNtlmStep2(nsCString &commandResponse, nsCString &response); + + nsresult DoGSSAPIStep1(const char *service, const char *username, nsCString &response); + nsresult DoGSSAPIStep2(nsCString &commandResponse, nsCString &response); + // Ouput stream for writing commands to the socket + nsCOMPtr<nsIOutputStream> m_outputStream; // this will be obtained from the transport interface + nsCOMPtr<nsIInputStream> m_inputStream; + + // Ouput stream for writing commands to the socket + nsCOMPtr<nsITransport> m_transport; + nsCOMPtr<nsIRequest> m_request; + + bool m_socketIsOpen; // mscott: we should look into keeping this state in the nsSocketTransport... + // I'm using it to make sure I open the socket the first time a URL is loaded into the connection + uint32_t m_flags; // used to store flag information + //uint32_t m_startPosition; + int32_t m_readCount; + + nsCOMPtr<nsIFile> m_tempMsgFile; // we currently have a hack where displaying a msg involves writing it to a temp file first + + // auth module for access to NTLM functions + nsCOMPtr<nsIAuthModule> m_authModule; + + // the following is a catch all for nsIChannel related data + nsCOMPtr<nsIURI> m_originalUrl; // the original url + nsCOMPtr<nsIURI> m_url; // the running url + nsCOMPtr<nsIStreamListener> m_channelListener; + nsCOMPtr<nsISupports> m_channelContext; + nsCOMPtr<nsILoadGroup> m_loadGroup; + nsLoadFlags mLoadFlags; + nsCOMPtr<nsIProgressEventSink> mProgressEventSink; + nsCOMPtr<nsIInterfaceRequestor> mCallbacks; + nsCOMPtr<nsISupports> mOwner; + nsCString mContentType; + nsCString mCharset; + int64_t mContentLength; + nsCOMPtr<nsILoadInfo> m_loadInfo; + + nsCString m_lastPasswordSent; // used to prefill the password prompt + + // private helper routine used by subclasses to quickly get a reference to the correct prompt dialog + // for a mailnews url. + nsresult GetPromptDialogFromUrl(nsIMsgMailNewsUrl * aMsgUrl, nsIPrompt ** aPromptDialog); + + // if a url isn't going to result in any content then we want to suppress calls to + // OnStartRequest, OnDataAvailable and OnStopRequest + bool mSuppressListenerNotifications; +}; + + +// This is is a subclass of nsMsgProtocol extends the parent class with AsyncWrite support. Protocols like smtp +// and news want to leverage aysnc write. We don't want everyone who inherits from nsMsgProtocol to have to +// pick up the extra overhead. +class NS_MSG_BASE nsMsgAsyncWriteProtocol : public nsMsgProtocol + , public nsSupportsWeakReference +{ +public: + NS_DECL_ISUPPORTS_INHERITED + + NS_IMETHOD Cancel(nsresult status) override; + + nsMsgAsyncWriteProtocol(nsIURI * aURL); + + // temporary over ride... + virtual nsresult PostMessage(nsIURI* url, nsIFile *postFile) override; + + // over ride the following methods from the base class + virtual nsresult SetupTransportState() override; + virtual nsresult SendData(const char * dataBuffer, bool aSuppressLogging = false) override; + nsCString mAsyncBuffer; + + // if we suspended the asynch write while waiting for more data to write then this will be TRUE + bool mSuspendedWrite; + nsCOMPtr<nsIRequest> m_WriteRequest; + nsCOMPtr<nsIAsyncOutputStream> mAsyncOutStream; + nsCOMPtr<nsIOutputStreamCallback> mProvider; + nsCOMPtr<nsIThread> mProviderThread; + + // because we are reading the post data in asychronously, it's possible that we aren't sending it + // out fast enough and the reading gets blocked. The following set of state variables are used to + // track this. + bool mSuspendedRead; + bool mInsertPeriodRequired; // do we need to insert a '.' as part of the unblocking process + + nsresult ProcessIncomingPostData(nsIInputStream *inStr, uint32_t count); + nsresult UnblockPostReader(); + nsresult UpdateSuspendedReadBytes(uint32_t aNewBytes, bool aAddToPostPeriodByteCount); + nsresult PostDataFinished(); // this is so we'll send out a closing '.' and release any state related to the post + + + // these two routines are used to pause and resume our loading of the file containing the contents + // we are trying to post. We call these routines when we aren't sending the bits out fast enough + // to keep up with the file read. + nsresult SuspendPostFileRead(); + nsresult ResumePostFileRead(); + nsresult UpdateSuspendedReadBytes(uint32_t aNewBytes); + void UpdateProgress(uint32_t aNewBytes); + nsMsgFilePostHelper * mFilePostHelper; // needs to be a weak reference +protected: + virtual ~nsMsgAsyncWriteProtocol(); + + // the streams for the pipe used to queue up data for the async write calls to the server. + // we actually re-use the same mOutStream variable in our parent class for the output + // stream to the socket channel. So no need for a new variable here. + nsCOMPtr<nsIInputStream> mInStream; + nsCOMPtr<nsIInputStream> mPostDataStream; + uint32_t mSuspendedReadBytes; // remaining # of bytes we need to read before + // the input stream becomes unblocked + uint32_t mSuspendedReadBytesPostPeriod; // # of bytes which need processed after we insert a '.' before + // the input stream becomes unblocked. + int64_t mFilePostSize; // used for determining progress on posting files. + uint32_t mNumBytesPosted; // used for deterimining progress on posting files + bool mGenerateProgressNotifications; // set during a post operation after we've started sending the post data... + + virtual nsresult CloseSocket() override; +}; + +#undef IMETHOD_VISIBILITY +#define IMETHOD_VISIBILITY NS_VISIBILITY_HIDDEN + +#endif /* nsMsgProtocol_h__ */ |