Bug #41199 parse out the language capabilitiy. We also needed to add the ability to not necessarily throw alert

dialogs just because we get a bad or nO response from the server. Some commands like LANGUAGE are "exploratory" in
nature and you don't care if they succeed or fail.
r=bienvenu
This commit is contained in:
mscott%netscape.com 2000-06-09 22:19:49 +00:00
Родитель 34194e3889
Коммит b7e2d08501
2 изменённых файлов: 171 добавлений и 118 удалений

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

@ -52,8 +52,8 @@ nsImapServerResponseParser::nsImapServerResponseParser(nsImapProtocol &imapProto
fCurrentCommandTag(nsnull),
fSelectedMailboxName(nsnull),
fIMAPstate(kNonAuthenticated),
fLastChunk(PR_FALSE),
fServerIsNetscape3xServer(PR_FALSE),
fLastChunk(PR_FALSE),
fServerIsNetscape3xServer(PR_FALSE),
m_shell(nsnull),
fServerConnection(imapProtocolConnection),
fHostSessionList(nsnull)
@ -71,6 +71,7 @@ nsImapServerResponseParser::nsImapServerResponseParser(nsImapProtocol &imapProto
fLastAlert = nsnull;
fDownloadingHeaders = PR_FALSE;
fFolderUIDValidity = 0;
fCRAMDigest = nsnull;
}
nsImapServerResponseParser::~nsImapServerResponseParser()
@ -85,9 +86,10 @@ nsImapServerResponseParser::~nsImapServerResponseParser()
PR_FREEIF( fManageListsUrl );
PR_FREEIF( fManageFiltersUrl );
PR_FREEIF( fSelectedMailboxName );
PR_FREEIF(fCRAMDigest);
NS_IF_RELEASE (fHostSessionList);
fCopyResponseKeyArray.RemoveAll();
NS_IF_RELEASE (fHostSessionList);
fCopyResponseKeyArray.RemoveAll();
}
PRBool nsImapServerResponseParser::LastCommandSuccessful()
@ -159,7 +161,7 @@ void nsImapServerResponseParser::InitializeState()
fCurrentCommandFailed = PR_FALSE;
}
void nsImapServerResponseParser::ParseIMAPServerResponse(const char *currentCommand)
void nsImapServerResponseParser::ParseIMAPServerResponse(const char *currentCommand, PRBool aIgnoreBadAndNOResponses)
{
NS_ASSERTION(currentCommand && *currentCommand != '\r' &&
@ -211,6 +213,12 @@ void nsImapServerResponseParser::ParseIMAPServerResponse(const char *currentComm
NS_ASSERTION((fNumberOfTaggedResponsesExpected - numberOfTaggedResponsesReceived) == 1,
" didn't get the number of tagged responses we expected");
numberOfTaggedResponsesReceived = fNumberOfTaggedResponsesExpected;
if (commandToken && !nsCRT::strcasecmp(commandToken, "authenticate") && placeInTokenString &&
!nsCRT::strncasecmp(placeInTokenString, "CRAM-MD5", nsCRT::strlen("CRAM-MD5")))
{
// we need to store the digest from the server if we are using CRAM-MD5.
cramResponse_data();
}
}
else
numberOfTaggedResponsesReceived++;
@ -224,11 +232,14 @@ void nsImapServerResponseParser::ParseIMAPServerResponse(const char *currentComm
} while (ContinueParse() && (numberOfTaggedResponsesReceived < fNumberOfTaggedResponsesExpected));
// check and see if the server is waiting for more input
// it's possible that we ate this + while parsing certain responses (like cram data),
// in these cases, the parsing routine for that specific command will manually set
// fWaitingForMoreClientInput so we don't lose that information....
if (*fNextToken == '+')
{
fWaitingForMoreClientInput = PR_TRUE;
}
else
else if (!fWaitingForMoreClientInput) // if we aren't still waiting for more input....
{
if (ContinueParse())
response_done();
@ -242,7 +253,7 @@ void nsImapServerResponseParser::ParseIMAPServerResponse(const char *currentComm
{
// a failed command may change the eIMAPstate
ProcessBadCommand(commandToken);
if (fReportingErrors)
if (fReportingErrors && !aIgnoreBadAndNOResponses)
fServerConnection.AlertUserEventFromServer(fCurrentLine);
}
}
@ -468,6 +479,8 @@ void nsImapServerResponseParser::ProcessBadCommand(const char *commandToken)
}
}
}
/*
response_data ::= "*" SPACE (resp_cond_state / resp_cond_bye /
mailbox_data / message_data / capability_data)
@ -528,7 +541,10 @@ void nsImapServerResponseParser::response_data()
case 'L':
if (!PL_strcasecmp(fNextToken, "LIST") || !PL_strcasecmp(fNextToken, "LSUB"))
mailbox_data();
else SetSyntaxError(PR_TRUE);
else if (!PL_strcasecmp(fNextToken, "LANGUAGE"))
language_data();
else
SetSyntaxError(PR_TRUE);
break;
case 'M':
if (!PL_strcasecmp(fNextToken, "MAILBOX"))
@ -1275,9 +1291,9 @@ void nsImapServerResponseParser::envelope_data()
fServerConnection.HandleMessageDownLoadLine(headerLine.GetBuffer(), PR_FALSE);
}
else
break;
// only fetch the next token if we aren't eating a parenthes
if (ContinueParse() && (*fNextToken != ')') || tableIndex < (int)(sizeof(EnvelopeTable) / sizeof(EnvelopeTable[0])) - 1 )
break;
// only fetch the next token if we aren't eating a parenthes
if (ContinueParse() && (*fNextToken != ')') || tableIndex < (int)(sizeof(EnvelopeTable) / sizeof(EnvelopeTable[0])) - 1 )
fNextToken = GetNextToken();
}
@ -1479,6 +1495,7 @@ void nsImapServerResponseParser::resp_cond_state()
if ((!PL_strcasecmp(fNextToken, "NO") ||
!PL_strcasecmp(fNextToken, "BAD") ) &&
fProcessingTaggedResponse)
fCurrentCommandFailed = PR_TRUE;
fNextToken = GetNextToken();
@ -1892,6 +1909,8 @@ void nsImapServerResponseParser::capability_data()
fCapabilityFlag |= kHasAuthLoginCapability;
else if (! PL_strcasecmp(fNextToken, "AUTH=PLAIN"))
fCapabilityFlag |= kHasAuthPlainCapability;
else if (! PL_strcasecmp(fNextToken, "AUTH=CRAM-MD5"))
fCapabilityFlag |= kHasCRAMCapability;
else if (! PL_strcasecmp(fNextToken, "X-NETSCAPE"))
fCapabilityFlag |= kHasXNetscapeCapability;
else if (! PL_strcasecmp(fNextToken, "XSENDER"))
@ -1920,6 +1939,8 @@ void nsImapServerResponseParser::capability_data()
fCapabilityFlag |= kLiteralPlusCapability;
else if (! PL_strcasecmp(fNextToken, "XAOL-OPTION"))
fCapabilityFlag |= kAOLImapCapability;
else if (! PL_strcasecmp(fNextToken, "LANGUAGE"))
fCapabilityFlag |= kHasLanguageCapability;
}
} while (fNextToken &&
!at_end_of_line() &&
@ -1990,12 +2011,36 @@ void nsImapServerResponseParser::xserverinfo_data()
} while (fNextToken && !at_end_of_line() && ContinueParse());
}
void nsImapServerResponseParser::language_data()
{
// we may want to go out and store the language returned to us
// by the language command in the host info session stuff.
// for now, just eat the language....
do
{
// eat each language returned to us
fNextToken = GetNextToken();
} while (fNextToken && !at_end_of_line() && ContinueParse());
}
// cram response data ::= "+" SPACE digest/challenge CRLF
// the server expects more client data after issuing it's challenge
void nsImapServerResponseParser::cramResponse_data()
{
fNextToken = GetNextToken();
fCRAMDigest = nsCRT::strdup(fNextToken);
fWaitingForMoreClientInput = PR_TRUE;
skip_to_CRLF();
}
void nsImapServerResponseParser::namespace_data()
{
EIMAPNamespaceType namespaceType = kPersonalNamespace;
PRBool namespacesCommitted = PR_FALSE;
const char* serverKey = fServerConnection.GetImapServerKey();
const char* serverKey = fServerConnection.GetImapServerKey();
while ((namespaceType != kUnknownNamespace) && ContinueParse())
{
fNextToken = GetNextToken();
@ -2044,6 +2089,9 @@ void nsImapServerResponseParser::namespace_data()
}
if (ContinueParse())
{
// add code to parse the TRANSLATE attribute if it is present....
// we'll also need to expand the name space code to take in the translated prefix name.
nsIMAPNamespace *newNamespace = new nsIMAPNamespace(namespaceType, namespacePrefix, namespaceDelimiter, PR_FALSE);
// add it to a temporary list in the host
if (newNamespace && fHostSessionList)

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

@ -46,11 +46,14 @@ public:
// Overridden from the base parser class
virtual PRBool LastCommandSuccessful();
virtual void HandleMemoryFailure();
virtual void HandleMemoryFailure();
virtual void ParseIMAPServerResponse(const char *currentCommand);
// aignoreBadAndNOResponses --> don't throw a error dialog if this command results in a NO or Bad response
// from the server..in other words the command is "exploratory" and we don't really care if it succeeds or fails.
// This value is typically FALSE for almost all cases.
virtual void ParseIMAPServerResponse(const char *currentCommand, PRBool aIgnoreBadAndNOResponses);
virtual void InitializeState();
PRBool CommandFailed();
PRBool CommandFailed();
enum eIMAPstate {
kNonAuthenticated,
@ -63,44 +66,44 @@ public:
#endif
} ;
virtual eIMAPstate GetIMAPstate();
virtual eIMAPstate GetIMAPstate();
virtual PRBool WaitingForMoreClientInput() { return fWaitingForMoreClientInput; };
const char *GetSelectedMailboxName(); // can be NULL
const char *GetSelectedMailboxName(); // can be NULL
// if we get a PREAUTH greeting from the server, initialize the parser to begin in
// the kAuthenticated state
void PreauthSetAuthenticatedState();
void PreauthSetAuthenticatedState();
// these functions represent the state of the currently selected
// folder
PRBool CurrentFolderReadOnly();
PRInt32 NumberOfMessages();
PRInt32 NumberOfRecentMessages();
PRInt32 NumberOfUnseenMessages();
PRInt32 FolderUID();
PRUint32 CurrentResponseUID();
PRUint32 HighestRecordedUID();
void CopyResponseUID(nsMsgKeyArray& keyArray);
void ClearCopyResponseUID();
// these functions represent the state of the currently selected
// folder
PRBool CurrentFolderReadOnly();
PRInt32 NumberOfMessages();
PRInt32 NumberOfRecentMessages();
PRInt32 NumberOfUnseenMessages();
PRInt32 FolderUID();
PRUint32 CurrentResponseUID();
PRUint32 HighestRecordedUID();
void CopyResponseUID(nsMsgKeyArray& keyArray);
void ClearCopyResponseUID();
PRBool IsNumericString(const char *string);
PRInt32 SizeOfMostRecentMessage();
PRInt32 SizeOfMostRecentMessage();
void SetTotalDownloadSize(PRInt32 newSize) { fTotalDownloadSize = newSize; }
nsImapSearchResultIterator *CreateSearchResultIterator();
void ResetSearchResultSequence() {fSearchResults->ResetSequence();}
// create a struct mailbox_spec from our info, used in
// libmsg c interface
nsImapMailboxSpec *CreateCurrentMailboxSpec(const char *mailboxName = NULL);
// zero stops a list recording of flags and causes the flags for
// each individual message to be sent back to libmsg
void ResetFlagInfo(int numberOfInterestingMessages);
// set this to false if you don't want to alert the user to server
// error messages
void SetReportingErrors(PRBool reportThem) { fReportingErrors=reportThem;}
nsImapSearchResultIterator *CreateSearchResultIterator();
void ResetSearchResultSequence() {fSearchResults->ResetSequence();}
// create a struct mailbox_spec from our info, used in
// libmsg c interface
nsImapMailboxSpec *CreateCurrentMailboxSpec(const char *mailboxName = NULL);
// zero stops a list recording of flags and causes the flags for
// each individual message to be sent back to libmsg
void ResetFlagInfo(int numberOfInterestingMessages);
// set this to false if you don't want to alert the user to server
// error messages
void SetReportingErrors(PRBool reportThem) { fReportingErrors=reportThem;}
PRBool GetReportingErrors() { return fReportingErrors; }
PRUint32 GetCapabilityFlag() { return fCapabilityFlag; }
@ -121,111 +124,113 @@ public:
const char *GetManageFolderUrl() {return fFolderAdminUrl;}
// Call this when adding a pipelined command to the session
void IncrementNumberOfTaggedResponsesExpected(const char *newExpectedTag);
// Call this when adding a pipelined command to the session
void IncrementNumberOfTaggedResponsesExpected(const char *newExpectedTag);
// Interrupt a Fetch, without really Interrupting (through netlib)
PRBool GetLastFetchChunkReceived();
void ClearLastFetchChunkReceived();
virtual PRUint16 SupportsUserFlags() { return fSupportsUserDefinedFlags; };
virtual PRUint16 SettablePermanentFlags() { return fSettablePermanentFlags;};
virtual PRUint16 SettablePermanentFlags() { return fSettablePermanentFlags;};
void SetFlagState(nsIImapFlagAndUidState *state);
PRBool GetDownloadingHeaders();
PRBool GetFillingInShell();
void UseCachedShell(nsIMAPBodyShell *cachedShell);
void SetHostSessionList(nsIImapHostSessionList *aHostSession);
void SetHostSessionList(nsIImapHostSessionList *aHostSession);
nsIImapHostSessionList *GetHostSessionList();
char *fCRAMDigest; // the digest returned by the server in response to authenticate using CRAM-MD5...
protected:
virtual void flags();
virtual void flags();
virtual void envelope_data();
virtual void xaolenvelope_data();
virtual void parse_address(nsCAutoString &addressLine);
virtual void internal_date();
virtual nsresult BeginMessageDownload(const char *content_type);
virtual void response_data();
virtual void resp_text();
virtual void resp_cond_state();
virtual void text_mime2();
virtual void text();
virtual void resp_text_code();
virtual void response_done();
virtual void response_tagged();
virtual void response_fatal();
virtual void resp_cond_bye();
virtual void mailbox_data();
virtual void numeric_mailbox_data();
virtual void capability_data();
virtual void xserverinfo_data();
virtual void xmailboxinfo_data();
virtual void namespace_data();
virtual void myrights_data();
virtual void acl_data();
virtual void bodystructure_data();
virtual void mime_data();
virtual void mime_part_data();
virtual void mime_header_data();
virtual void msg_fetch();
virtual void msg_obsolete();
virtual void msg_fetch_headers(const char *partNum);
virtual void msg_fetch_content(PRBool chunk, PRInt32 origin, const char *content_type);
virtual PRBool msg_fetch_quoted(PRBool chunk, PRInt32 origin);
virtual PRBool msg_fetch_literal(PRBool chunk, PRInt32 origin);
virtual void mailbox_list(PRBool discoveredFromLsub);
virtual void mailbox(nsImapMailboxSpec *boxSpec);
virtual void ProcessOkCommand(const char *commandToken);
virtual void ProcessBadCommand(const char *commandToken);
virtual void PreProcessCommandToken(const char *commandToken,
const char *currentCommand);
virtual void PostProcessEndOfLine();
virtual void response_data();
virtual void resp_text();
virtual void resp_cond_state();
virtual void text_mime2();
virtual void text();
virtual void language_data();
virtual void cramResponse_data();
virtual void resp_text_code();
virtual void response_done();
virtual void response_tagged();
virtual void response_fatal();
virtual void resp_cond_bye();
virtual void mailbox_data();
virtual void numeric_mailbox_data();
virtual void capability_data();
virtual void xserverinfo_data();
virtual void xmailboxinfo_data();
virtual void namespace_data();
virtual void myrights_data();
virtual void acl_data();
virtual void bodystructure_data();
virtual void mime_data();
virtual void mime_part_data();
virtual void mime_header_data();
virtual void msg_fetch();
virtual void msg_obsolete();
virtual void msg_fetch_headers(const char *partNum);
virtual void msg_fetch_content(PRBool chunk, PRInt32 origin, const char *content_type);
virtual PRBool msg_fetch_quoted(PRBool chunk, PRInt32 origin);
virtual PRBool msg_fetch_literal(PRBool chunk, PRInt32 origin);
virtual void mailbox_list(PRBool discoveredFromLsub);
virtual void mailbox(nsImapMailboxSpec *boxSpec);
virtual void ProcessOkCommand(const char *commandToken);
virtual void ProcessBadCommand(const char *commandToken);
virtual void PreProcessCommandToken(const char *commandToken,
const char *currentCommand);
virtual void PostProcessEndOfLine();
// Overridden from the nsIMAPGenericParser, to retrieve the next line
// from the open socket.
virtual PRBool GetNextLineForParser(char **nextLine);
virtual void end_of_line();
// overriden to do logging
virtual void SetSyntaxError(PRBool error);
virtual void SetSyntaxError(PRBool error);
private:
PRBool fProcessingTaggedResponse;
PRBool fCurrentCommandFailed;
PRBool fReportingErrors;
PRBool fCurrentFolderReadOnly;
PRBool fCurrentLineContainedFlagInfo;
imapMessageFlagsType fSavedFlagInfo;
PRBool fProcessingTaggedResponse;
PRBool fCurrentCommandFailed;
PRBool fReportingErrors;
PRBool fCurrentFolderReadOnly;
PRBool fCurrentLineContainedFlagInfo;
imapMessageFlagsType fSavedFlagInfo;
PRUint16 fSupportsUserDefinedFlags;
PRUint16 fSettablePermanentFlags;
PRUint16 fSettablePermanentFlags;
PRInt32 fFolderUIDValidity;
PRInt32 fNumberOfUnseenMessages;
PRInt32 fNumberOfExistingMessages;
PRInt32 fNumberOfRecentMessages;
PRUint32 fCurrentResponseUID;
PRUint32 fHighestRecordedUID;
PRInt32 fSizeOfMostRecentMessage;
PRInt32 fFolderUIDValidity;
PRInt32 fNumberOfUnseenMessages;
PRInt32 fNumberOfExistingMessages;
PRInt32 fNumberOfRecentMessages;
PRUint32 fCurrentResponseUID;
PRUint32 fHighestRecordedUID;
PRInt32 fSizeOfMostRecentMessage;
PRInt32 fTotalDownloadSize;
int fNumberOfTaggedResponsesExpected;
char *fCurrentCommandTag;
nsCString fZeroLengthMessageUidString;
int fNumberOfTaggedResponsesExpected;
char *fSelectedMailboxName;
nsImapSearchResultSequence *fSearchResults;
nsCOMPtr <nsIImapFlagAndUidState> fFlagState; // NOT owned by us, it's a copy, do not destroy
eIMAPstate fIMAPstate;
char *fCurrentCommandTag;
nsCString fZeroLengthMessageUidString;
char *fSelectedMailboxName;
nsImapSearchResultSequence *fSearchResults;
nsCOMPtr <nsIImapFlagAndUidState> fFlagState; // NOT owned by us, it's a copy, do not destroy
eIMAPstate fIMAPstate;
PRBool fWaitingForMoreClientInput;
PRUint32 fCapabilityFlag;
@ -255,10 +260,10 @@ private:
nsIMAPBodyShell *m_shell;
// The connection object
nsImapProtocol &fServerConnection;
nsImapProtocol &fServerConnection;
nsIImapHostSessionList *fHostSessionList;
nsMsgKeyArray fCopyResponseKeyArray;
nsMsgKeyArray fCopyResponseKeyArray;
};
#endif