/* -*- 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 nsImapProtocol_h___ #define nsImapProtocol_h___ #include "mozilla/Attributes.h" #include "nsIImapProtocol.h" #include "nsIImapUrl.h" #include "nsMsgProtocol.h" #include "nsIStreamListener.h" #include "nsIAsyncOutputStream.h" #include "nsIAsyncInputStream.h" #include "nsImapCore.h" #include "nsStringGlue.h" #include "nsIProgressEventSink.h" #include "nsIInterfaceRequestor.h" #include "nsIInterfaceRequestorUtils.h" #include "nsISocketTransport.h" #include "nsIInputStreamPump.h" // imap event sinks #include "nsIImapMailFolderSink.h" #include "nsIImapServerSink.h" #include "nsIImapMessageSink.h" // UI Thread proxy helper #include "nsIImapProtocolSink.h" #include "nsImapServerResponseParser.h" #include "nsImapFlagAndUidState.h" #include "nsIMAPNamespace.h" #include "nsTArray.h" #include "nsWeakPtr.h" #include "nsMsgLineBuffer.h" // we need this to use the nsMsgLineStreamBuffer helper class... #include "nsIInputStream.h" #include "nsIMsgIncomingServer.h" #include "nsCOMArray.h" #include "nsIThread.h" #include "nsIRunnable.h" #include "nsIImapMockChannel.h" #include "nsILoadGroup.h" #include "nsCOMPtr.h" #include "nsIImapIncomingServer.h" #include "nsIMsgWindow.h" #include "nsIImapHeaderXferInfo.h" #include "nsMsgLineBuffer.h" #include "nsIAsyncInputStream.h" #include "nsITimer.h" #include "nsAutoPtr.h" #include "nsIMsgFolder.h" #include "nsIMsgAsyncPrompter.h" #include "mozilla/ReentrantMonitor.h" #include "nsSyncRunnableHelpers.h" #include "nsICacheEntryOpenCallback.h" class nsIMAPMessagePartIDArray; class nsIMsgIncomingServer; class nsIPrefBranch; class nsIMAPMailboxInfo; #define kDownLoadCacheSize 16000 // was 1536 - try making it bigger typedef struct _msg_line_info { const char *adoptedMessageLine; uint32_t uidOfMessage; } msg_line_info; class nsMsgImapLineDownloadCache : public nsIImapHeaderInfo, public nsByteArray { public: NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIIMAPHEADERINFO nsMsgImapLineDownloadCache(); uint32_t CurrentUID(); uint32_t SpaceAvailable(); bool CacheEmpty(); msg_line_info *GetCurrentLineInfo(); private: virtual ~nsMsgImapLineDownloadCache(); msg_line_info *fLineInfo; int32_t m_msgSize; }; #define kNumHdrsToXfer 10 class nsMsgImapHdrXferInfo : public nsIImapHeaderXferInfo { public: NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIIMAPHEADERXFERINFO nsMsgImapHdrXferInfo(); void ResetAll(); // reset HeaderInfos for re-use void ReleaseAll(); // release HeaderInfos (frees up memory) // this will return null if we're full, in which case the client code // should transfer the headers and retry. nsIImapHeaderInfo *StartNewHdr(); // call when we've finished adding lines to current hdr void FinishCurrentHdr(); private: virtual ~nsMsgImapHdrXferInfo(); nsCOMArray m_hdrInfos; int32_t m_nextFreeHdrInfo; }; // State Flags (Note, I use the word state in terms of storing // state information about the connection (authentication, have we sent // commands, etc. I do not intend it to refer to protocol state) // Use these flags in conjunction with SetFlag/TestFlag/ClearFlag instead // of creating PRBools for everything.... #define IMAP_RECEIVED_GREETING 0x00000001 /* should we pause for the next read */ #define IMAP_CONNECTION_IS_OPEN 0x00000004 /* is the connection currently open? */ #define IMAP_WAITING_FOR_DATA 0x00000008 #define IMAP_CLEAN_UP_URL_STATE 0x00000010 // processing clean up url state #define IMAP_ISSUED_LANGUAGE_REQUEST 0x00000020 // make sure we only issue the language request once per connection... #define IMAP_ISSUED_COMPRESS_REQUEST 0x00000040 // make sure we only request compression once class nsImapProtocol : public nsIImapProtocol, public nsIRunnable, public nsIInputStreamCallback, public nsSupportsWeakReference, public nsMsgProtocol, public nsIImapProtocolSink, public nsIMsgAsyncPromptListener { public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIINPUTSTREAMCALLBACK nsImapProtocol(); virtual nsresult ProcessProtocolState(nsIURI * url, nsIInputStream * inputStream, uint64_t sourceOffset, uint32_t length) override; // nsIRunnable method NS_IMETHOD Run() override; ////////////////////////////////////////////////////////////////////////////////// // we support the nsIImapProtocol interface ////////////////////////////////////////////////////////////////////////////////// NS_DECL_NSIIMAPPROTOCOL ////////////////////////////////////////////////////////////////////////////////// // we support the nsIImapProtocolSink interface ////////////////////////////////////////////////////////////////////////////////// NS_DECL_NSIIMAPPROTOCOLSINK NS_DECL_NSIMSGASYNCPROMPTLISTENER // message id string utilities. uint32_t CountMessagesInIdString(const char *idString); static bool HandlingMultipleMessages(const nsCString &messageIdString); // escape slashes and double quotes in username/passwords for insecure login. static void EscapeUserNamePasswordString(const char *strToEscape, nsCString *resultStr); // used to start fetching a message. void GetShouldDownloadAllHeaders(bool *aResult); void GetArbitraryHeadersToDownload(nsCString &aResult); virtual void AdjustChunkSize(); virtual void FetchMessage(const nsCString &messageIds, nsIMAPeFetchFields whatToFetch, const char *fetchModifier = nullptr, uint32_t startByte = 0, uint32_t numBytes = 0, char *part = 0); void FetchTryChunking(const nsCString &messageIds, nsIMAPeFetchFields whatToFetch, bool idIsUid, char *part, uint32_t downloadSize, bool tryChunking); virtual void PipelinedFetchMessageParts(nsCString &uid, nsIMAPMessagePartIDArray *parts); void FallbackToFetchWholeMsg(const nsCString &messageId, uint32_t messageSize); // used when streaming a message fetch virtual nsresult BeginMessageDownLoad(uint32_t totalSize, // for user, headers and body const char *contentType); // some downloads are header only virtual void HandleMessageDownLoadLine(const char *line, bool isPartialLine, char *lineCopy=nullptr); virtual void NormalMessageEndDownload(); virtual void AbortMessageDownLoad(); virtual void PostLineDownLoadEvent(const char *line, uint32_t uid); void FlushDownloadCache(); virtual void SetMailboxDiscoveryStatus(EMailboxDiscoverStatus status); virtual EMailboxDiscoverStatus GetMailboxDiscoveryStatus(); virtual void ProcessMailboxUpdate(bool handlePossibleUndo); // Send log output... void Log(const char *logSubName, const char *extraInfo, const char *logData); static void LogImapUrl(const char *logMsg, nsIImapUrl *imapUrl); // Comment from 4.5: We really need to break out the thread synchronizer from the // connection class...Not sure what this means bool GetPseudoInterrupted(); void PseudoInterrupt(bool the_interrupt); uint32_t GetMessageSize(const char * messageId, bool idsAreUids); bool GetSubscribingNow(); bool DeathSignalReceived(); void ResetProgressInfo(); void SetActive(bool active); bool GetActive(); bool GetShowAttachmentsInline(); // Sets whether or not the content referenced by the current ActiveEntry has been modified. // Used for MIME parts on demand. void SetContentModified(IMAP_ContentModifiedType modified); bool GetShouldFetchAllParts(); bool GetIgnoreExpunges() {return m_ignoreExpunges;} // Generic accessors required by the imap parser char * CreateNewLineFromSocket(); nsresult GetConnectionStatus(); void SetConnectionStatus(nsresult status); // Cleanup the connection and shutdown the thread. void TellThreadToDie(); const nsCString& GetImapHostName(); // return the host name from the url for the // current connection const nsCString& GetImapUserName(); // return the user name from the identity const char* GetImapServerKey(); // return the user name from the incoming server; // state set by the imap parser... void NotifyMessageFlags(imapMessageFlagsType flags, const nsACString &keywords, nsMsgKey key, uint64_t highestModSeq); void NotifySearchHit(const char * hitLine); // Event handlers for the imap parser. void DiscoverMailboxSpec(nsImapMailboxSpec * adoptedBoxSpec); void AlertUserEventUsingName(const char* aMessageId); void AlertUserEvent(const char * message); void AlertUserEventFromServer(const char * aServerEvent, bool aForIdle = false); void ProgressEventFunctionUsingName(const char* aMsgId); void ProgressEventFunctionUsingNameWithString(const char* aMsgName, const char * aExtraInfo); void PercentProgressUpdateEvent(char16_t *message, int64_t currentProgress, int64_t maxProgress); void ShowProgress(); // utility function calls made by the server void Copy(const char * messageList, const char *destinationMailbox, bool idsAreUid); void Search(const char * searchCriteria, bool useUID, bool notifyHit = true); // imap commands issued by the parser void Store(const nsCString &aMessageList, const char * aMessageData, bool aIdsAreUid); void ProcessStoreFlags(const nsCString &messageIds, bool idsAreUids, imapMessageFlagsType flags, bool addFlags); void IssueUserDefinedMsgCommand(const char *command, const char * messageList); void FetchMsgAttribute(const nsCString &messageIds, const nsCString &attribute); void Expunge(); void UidExpunge(const nsCString &messageSet); void Close(bool shuttingDown = false, bool waitForResponse = true); void Check(); void SelectMailbox(const char *mailboxName); // more imap commands void Logout(bool shuttingDown = false, bool waitForResponse = true); void Noop(); void XServerInfo(); void Netscape(); void XMailboxInfo(const char *mailboxName); void XAOL_Option(const char *option); void MailboxData(); void GetMyRightsForFolder(const char *mailboxName); void Bodystructure(const nsCString &messageId, bool idIsUid); void PipelinedFetchMessageParts(const char *uid, nsIMAPMessagePartIDArray *parts); // this function does not ref count!!! be careful!!! nsIImapUrl *GetCurrentUrl() {return m_runningUrl;} // acl and namespace stuff // notifies libmsg that we have a new personal/default namespace that we're using void CommitNamespacesForHostEvent(); // notifies libmsg that we have new capability data for the current host void CommitCapability(); // Adds a set of rights for a given user on a given mailbox on the current host. // if userName is NULL, it means "me," or MYRIGHTS. // rights is a single string of rights, as specified by RFC2086, the IMAP ACL extension. void AddFolderRightsForUser(const char *mailboxName, const char *userName, const char *rights); // Clears all rights for the current folder, for all users. void ClearAllFolderRights(); void RefreshFolderACLView(const char *mailboxName, nsIMAPNamespace *nsForMailbox); nsresult SetFolderAdminUrl(const char *mailboxName); void HandleMemoryFailure(); void HandleCurrentUrlError(); // UIDPLUS extension void SetCopyResponseUid(const char* msgIdString); // Quota support void UpdateFolderQuotaData(nsCString& aQuotaRoot, uint32_t aUsed, uint32_t aMax); bool GetPreferPlainText() { return m_preferPlainText; } int32_t GetCurFetchSize() { return m_curFetchSize; } const nsString &GetEmptyMimePartString() { return m_emptyMimePartString; } private: virtual ~nsImapProtocol(); // the following flag is used to determine when a url is currently being run. It is cleared when we // finish processng a url and it is set whenever we call Load on a url bool m_urlInProgress; nsCOMPtr m_runningUrl; // the nsIImapURL that is currently running nsCOMPtr m_runningUrlLatest; nsImapAction m_imapAction; // current imap action associated with this connnection... nsCString m_hostName; nsCString m_userName; nsCString m_serverKey; nsCString m_realHostName; char *m_dataOutputBuf; RefPtr m_inputStreamBuffer; uint32_t m_allocatedSize; // allocated size uint32_t m_totalDataSize; // total data size uint32_t m_curReadIndex; // current read index nsCString m_trashFolderName; // Ouput stream for writing commands to the socket nsCOMPtr m_transport; nsCOMPtr m_channelInputStream; nsCOMPtr m_channelOutputStream; nsCOMPtr m_mockChannel; // this is the channel we should forward to people uint32_t m_bytesToChannel; bool m_fetchingWholeMessage; //nsCOMPtr mAsyncReadRequest; // we're going to cancel this when we're done with the conn. // ******* Thread support ******* nsCOMPtr m_iThread; PRThread *m_thread; mozilla::ReentrantMonitor m_dataAvailableMonitor; // used to notify the arrival of data from the server mozilla::ReentrantMonitor m_urlReadyToRunMonitor; // used to notify the arrival of a new url to be processed mozilla::ReentrantMonitor m_pseudoInterruptMonitor; mozilla::ReentrantMonitor m_dataMemberMonitor; mozilla::ReentrantMonitor m_threadDeathMonitor; mozilla::ReentrantMonitor m_waitForBodyIdsMonitor; mozilla::ReentrantMonitor m_fetchBodyListMonitor; mozilla::ReentrantMonitor m_passwordReadyMonitor; mozilla::Mutex mLock; // If we get an async password prompt, this is where the UI thread // stores the password, before notifying the imap thread of the password // via the m_passwordReadyMonitor. nsCString m_password; // Set to the result of nsImapServer::PromptPassword nsresult m_passwordStatus; bool m_passwordObtained; bool m_imapThreadIsRunning; void ImapThreadMainLoop(void); nsresult m_connectionStatus; nsCString m_connectionType; bool m_nextUrlReadyToRun; nsWeakPtr m_server; RefPtr m_imapMailFolderSink; RefPtr m_imapMessageSink; RefPtr m_imapServerSink; RefPtr m_imapServerSinkLatest; RefPtr m_imapProtocolSink; // helper function to setup imap sink interface proxies nsresult SetupSinkProxy(); // End thread support stuff bool GetDeleteIsMoveToTrash(); bool GetShowDeletedMessages(); nsCString m_currentCommand; nsImapServerResponseParser m_parser; nsImapServerResponseParser& GetServerStateParser() { return m_parser; } void HandleIdleResponses(); virtual bool ProcessCurrentURL(); void EstablishServerConnection(); virtual void ParseIMAPandCheckForNewMail(const char* commandString = nullptr, bool ignoreBadNOResponses = false); // biff void PeriodicBiff(); void SendSetBiffIndicatorEvent(nsMsgBiffState newState); bool CheckNewMail(); // folder opening and listing header functions void FolderHeaderDump(uint32_t *msgUids, uint32_t msgCount); void FolderMsgDump(uint32_t *msgUids, uint32_t msgCount, nsIMAPeFetchFields fields); void FolderMsgDumpLoop(uint32_t *msgUids, uint32_t msgCount, nsIMAPeFetchFields fields); void WaitForPotentialListOfBodysToFetch(uint32_t **msgIdList, uint32_t &msgCount); void HeaderFetchCompleted(); void UploadMessageFromFile(nsIFile* file, const char* mailboxName, PRTime date, imapMessageFlagsType flags, nsCString &keywords); // mailbox name utilities. void CreateEscapedMailboxName(const char *rawName, nsCString &escapedName); void SetupMessageFlagsString(nsCString & flagString, imapMessageFlagsType flags, uint16_t userFlags); // body fetching listing data bool m_fetchBodyListIsNew; uint32_t m_fetchBodyCount; uint32_t *m_fetchBodyIdList; // initialization function given a new url and transport layer nsresult SetupWithUrl(nsIURI * aURL, nsISupports* aConsumer); void ReleaseUrlState(bool rerunningUrl); // release any state that is stored on a per action basis. /** * Last ditch effort to run the url without using an imap connection. * If it turns out that we don't need to run the url at all (e.g., we're * trying to download a single message for offline use and it has already * been downloaded, this function will send the appropriate notifications. * * @returns true if the url has been run locally, or doesn't need to be run. */ bool TryToRunUrlLocally(nsIURI *aURL, nsISupports *aConsumer); //////////////////////////////////////////////////////////////////////////////////////// // Communication methods --> Reading and writing protocol //////////////////////////////////////////////////////////////////////////////////////// // SendData not only writes the NULL terminated data in dataBuffer to our output stream // but it also informs the consumer that the data has been written to the stream. // aSuppressLogging --> set to true if you wish to suppress logging for this particular command. // this is useful for making sure we don't log authenication information like the user's password (which was // encoded anyway), but still we shouldn't add that information to the log. nsresult SendData(const char * dataBuffer, bool aSuppressLogging = false) override; // state ported over from 4.5 bool m_pseudoInterrupted; bool m_active; bool m_folderNeedsSubscribing; bool m_folderNeedsACLRefreshed; bool m_threadShouldDie; // use to prevent re-entering TellThreadToDie. bool m_inThreadShouldDie; // if the UI thread has signalled the IMAP thread to die, and the // connection has timed out, this will be set to FALSE. bool m_safeToCloseConnection; nsImapFlagAndUidState *m_flagState; nsMsgBiffState m_currentBiffState; // manage the IMAP server command tags // 11 = enough memory for the decimal representation of MAX_UINT + trailing nul char m_currentServerCommandTag[11]; uint32_t m_currentServerCommandTagNumber; void IncrementCommandTagNumber(); const char *GetServerCommandTag(); void StartTLS(); // login related methods. nsresult GetPassword(nsCString &password, bool aNewPasswordRequested); #ifdef MOZ_MAILNEWS_OAUTH2 void InitPrefAuthMethods(int32_t authMethodPrefValue, nsIMsgIncomingServer *aServer); #else void InitPrefAuthMethods(int32_t authMethodPrefValue); #endif nsresult ChooseAuthMethod(); void MarkAuthMethodAsFailed(eIMAPCapabilityFlags failedAuthMethod); void ResetAuthMethods(); // All of these methods actually issue protocol void Capability(); // query host for capabilities. void ID(); // send RFC 2971 app info to server void EnableCondStore(); void StartCompressDeflate(); nsresult BeginCompressing(); void Language(); // set the language on the server if it supports it void Namespace(); void InsecureLogin(const char *userName, const nsCString &password); nsresult AuthLogin(const char *userName, const nsCString &password, eIMAPCapabilityFlag flag); nsresult SendDataParseIMAPandCheckForNewMail(const char *data, const char *command); void ProcessAuthenticatedStateURL(); void ProcessAfterAuthenticated(); void ProcessSelectedStateURL(); bool TryToLogon(); // Process Authenticated State Url used to be one giant if statement. I've broken out a set of actions // based on the imap action passed into the url. The following functions are imap protocol handlers for // each action. They are called by ProcessAuthenticatedStateUrl. void OnLSubFolders(); void OnAppendMsgFromFile(); char *GetFolderPathString(); // OK to call from UI thread char * OnCreateServerSourceFolderPathString(); char * OnCreateServerDestinationFolderPathString(); nsresult CreateServerSourceFolderPathString(char **result); void OnCreateFolder(const char * aSourceMailbox); void OnEnsureExistsFolder(const char * aSourceMailbox); void OnSubscribe(const char * aSourceMailbox); void OnUnsubscribe(const char * aSourceMailbox); void RefreshACLForFolderIfNecessary(const char * mailboxName); void RefreshACLForFolder(const char * aSourceMailbox); void GetACLForFolder(const char *aMailboxName); void OnRefreshAllACLs(); void OnListFolder(const char * aSourceMailbox, bool aBool); void OnStatusForFolder(const char * sourceMailbox); void OnDeleteFolder(const char * aSourceMailbox); void OnRenameFolder(const char * aSourceMailbox); void OnMoveFolderHierarchy(const char * aSourceMailbox); void DeleteFolderAndMsgs(const char * aSourceMailbox); void RemoveMsgsAndExpunge(); void FindMailboxesIfNecessary(); void CreateMailbox(const char *mailboxName); void DeleteMailbox(const char *mailboxName); void RenameMailbox(const char *existingName, const char *newName); void RemoveHierarchyDelimiter(nsCString &mailboxName); bool CreateMailboxRespectingSubscriptions(const char *mailboxName); bool DeleteMailboxRespectingSubscriptions(const char *mailboxName); bool RenameMailboxRespectingSubscriptions(const char *existingName, const char *newName, bool reallyRename); // notify the fe that a folder was deleted void FolderDeleted(const char *mailboxName); // notify the fe that a folder creation failed void FolderNotCreated(const char *mailboxName); // notify the fe that a folder was deleted void FolderRenamed(const char *oldName, const char *newName); bool FolderIsSelected(const char *mailboxName); bool MailboxIsNoSelectMailbox(const char *mailboxName); nsCString CreatePossibleTrashName(const char *prefix); bool FolderNeedsACLInitialized(const char *folderName); void DiscoverMailboxList(); void DiscoverAllAndSubscribedBoxes(); void MailboxDiscoveryFinished(); void NthLevelChildList(const char *onlineMailboxPrefix, int32_t depth); // LIST SUBSCRIBED command (from RFC 5258) crashes some servers. so we need to // identify those servers bool GetListSubscribedIsBrokenOnServer(); bool IsExtraSelectNeeded(); void Lsub(const char *mailboxPattern, bool addDirectoryIfNecessary); void List(const char *mailboxPattern, bool addDirectoryIfNecessary, bool useXLIST = false); void Subscribe(const char *mailboxName); void Unsubscribe(const char *mailboxName); void Idle(); void EndIdle(bool waitForResponse = true); // Some imap servers include the mailboxName following the dir-separator in the list of // subfolders of the mailboxName. In fact, they are the same. So we should decide if // we should delete such subfolder and provide feedback if the delete operation succeed. bool DeleteSubFolders(const char* aMailboxName, bool & aDeleteSelf); bool RenameHierarchyByHand(const char *oldParentMailboxName, const char *newParentMailboxName); bool RetryUrl(); nsresult GlobalInitialization(nsIPrefBranch *aPrefBranch); nsresult Configure(int32_t TooFastTime, int32_t IdealTime, int32_t ChunkAddSize, int32_t ChunkSize, int32_t ChunkThreshold, bool FetchByChunks); nsresult GetMsgWindow(nsIMsgWindow ** aMsgWindow); // End Process AuthenticatedState Url helper methods virtual char const *GetType() override {return "imap";} // Quota support void GetQuotaDataIfSupported(const char *aBoxName); // CondStore support - true if server supports it, and the user hasn't disabled it. bool UseCondStore(); // false if pref "mail.server.serverxxx.use_condstore" is false; bool m_useCondStore; // COMPRESS=DEFLATE support - true if server supports it, and the user hasn't disabled it. bool UseCompressDeflate(); // false if pref "mail.server.serverxxx.use_compress_deflate" is false; bool m_useCompressDeflate; // these come from the nsIDBFolderInfo in the msgDatabase and // are initialized in nsImapProtocol::SetupWithUrl. uint64_t mFolderLastModSeq; int32_t mFolderTotalMsgCount; uint32_t mFolderHighestUID; uint32_t mFolderNumDeleted; bool m_isGmailServer; nsTArray mCustomDBHeaders; nsTArray mCustomHeaders; bool m_trackingTime; PRTime m_startTime; PRTime m_endTime; PRTime m_lastActiveTime; int32_t m_tooFastTime; int32_t m_idealTime; int32_t m_chunkAddSize; int32_t m_chunkStartSize; bool m_fetchByChunks; bool m_sendID; int32_t m_curFetchSize; bool m_ignoreExpunges; eIMAPCapabilityFlags m_prefAuthMethods; // set of capability flags (in nsImapCore.h) for auth methods eIMAPCapabilityFlags m_failedAuthMethods; // ditto eIMAPCapabilityFlag m_currentAuthMethod; // exactly one capability flag, or 0 int32_t m_socketType; int32_t m_chunkSize; int32_t m_chunkThreshold; RefPtr m_downloadLineCache; RefPtr m_hdrDownloadCache; nsCOMPtr m_curHdrInfo; // mapping between mailboxes and the corresponding folder flags nsDataHashtable m_standardListMailboxes; // mapping between special xlist mailboxes and the corresponding folder flags nsDataHashtable m_specialXListMailboxes; nsCOMPtr m_hostSessionList; bool m_fromHeaderSeen; // these settings allow clients to override various pieces of the connection info from the url bool m_overRideUrlConnectionInfo; nsCString m_logonHost; nsCString m_logonCookie; int16_t m_logonPort; nsString mAcceptLanguages; // progress stuff void SetProgressString(const char* stringName); nsString m_progressString; nsCString m_progressStringName; int32_t m_progressIndex; int32_t m_progressCount; nsCString m_lastProgressStringName; int32_t m_lastPercent; int64_t m_lastProgressTime; bool m_notifySearchHit; bool m_checkForNewMailDownloadsHeaders; bool m_needNoop; bool m_idle; bool m_useIdle; int32_t m_noopCount; bool m_autoSubscribe, m_autoUnsubscribe, m_autoSubscribeOnOpen; bool m_closeNeededBeforeSelect; bool m_retryUrlOnError; bool m_preferPlainText; nsCString m_forceSelectValue; bool m_forceSelect; int32_t m_uidValidity; // stored uid validity for the selected folder. enum EMailboxHierarchyNameState { kNoOperationInProgress, kDiscoverBaseFolderInProgress, kDiscoverTrashFolderInProgress, kDeleteSubFoldersInProgress, kListingForInfoOnly, kListingForInfoAndDiscovery, kDiscoveringNamespacesOnly, kXListing, kListingForFolderFlags, kListingForCreate }; EMailboxHierarchyNameState m_hierarchyNameState; EMailboxDiscoverStatus m_discoveryStatus; nsTArray m_listedMailboxList; nsTArray * m_deletableChildren; uint32_t m_flagChangeCount; PRTime m_lastCheckTime; bool CheckNeeded(); nsString m_emptyMimePartString; #ifdef MOZ_MAILNEWS_OAUTH2 RefPtr mOAuth2Support; #endif }; // This small class is a "mock" channel because it is a mockery of the imap channel's implementation... // it's a light weight channel that we can return to necko when they ask for a channel on a url before // we actually have an imap protocol instance around which can run the url. Please see my comments in // nsIImapMockChannel.idl for more details.. // // Threading concern: This class lives entirely in the UI thread. class nsICacheEntry; class nsImapMockChannel : public nsIImapMockChannel , public nsICacheEntryOpenCallback , public nsITransportEventSink , public nsSupportsWeakReference { public: friend class nsImapProtocol; NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIIMAPMOCKCHANNEL NS_DECL_NSICHANNEL NS_DECL_NSIREQUEST NS_DECL_NSICACHEENTRYOPENCALLBACK NS_DECL_NSITRANSPORTEVENTSINK nsImapMockChannel(); static nsresult Create (const nsIID& iid, void **result); nsresult RunOnStopRequestFailure(); protected: virtual ~nsImapMockChannel(); nsCOMPtr m_url; nsCOMPtr m_originalUrl; nsCOMPtr m_loadGroup; nsCOMPtr m_loadInfo; nsCOMPtr m_channelListener; nsISupports * m_channelContext; nsresult m_cancelStatus; nsLoadFlags mLoadFlags; nsCOMPtr mProgressEventSink; nsCOMPtr mCallbacks; nsCOMPtr mOwner; nsCOMPtr mSecurityInfo; nsCOMPtr mCacheRequest; // the request associated with a read from the cache nsCString mContentType; nsCString mCharset; nsWeakPtr mProtocol; bool mChannelClosed; bool mReadingFromCache; bool mTryingToReadPart; int64_t mContentLength; // cache related helper methods nsresult OpenCacheEntry(); // makes a request to the cache service for a cache entry for a url bool ReadFromLocalCache(); // attempts to read the url out of our local (offline) cache.... nsresult ReadFromImapConnection(); // creates a new imap connection to read the url nsresult ReadFromMemCache(nsICacheEntry *entry); // attempts to read the url out of our memory cache nsresult NotifyStartEndReadFromCache(bool start); // we end up daisy chaining multiple nsIStreamListeners into the load process. nsresult SetupPartExtractorListener(nsIImapUrl * aUrl, nsIStreamListener * aConsumer); }; // This class contains the name of a mailbox and whether or not // its children have been listed. class nsIMAPMailboxInfo { public: nsIMAPMailboxInfo(const nsACString &aName, char aDelimiter); virtual ~nsIMAPMailboxInfo(); void SetChildrenListed(bool childrenListed); bool GetChildrenListed(); const nsACString& GetMailboxName(); char GetDelimiter(); protected: nsCString mMailboxName; bool mChildrenListed; char mDelimiter; }; #endif // nsImapProtocol_h___