diff options
author | Dmitry Isaikin <isaikin-dmitry@yandex.ru> | 2016-05-19 20:58:38 +0400 |
---|---|---|
committer | HoĆ V. DINH <dinh.viet.hoa@gmail.com> | 2016-05-19 09:58:38 -0700 |
commit | 6ea3534c94ced99a10682916c2718be8b93056da (patch) | |
tree | ea797cad294800cef0ca4a3b03dbc72230894c47 | |
parent | 6a720fd8bf82d6220330f148ca8ad351b690a9fd (diff) |
Store last server response on login command in case of parse error (#1436)
-rw-r--r-- | src/async/imap/MCIMAPCheckAccountOperation.cpp | 8 | ||||
-rw-r--r-- | src/async/imap/MCIMAPCheckAccountOperation.h | 2 | ||||
-rw-r--r-- | src/core/imap/MCIMAPSession.cpp | 19 | ||||
-rw-r--r-- | src/core/imap/MCIMAPSession.h | 3 | ||||
-rw-r--r-- | src/objc/abstract/MCOConstants.h | 2 | ||||
-rw-r--r-- | src/objc/imap/MCOIMAPCheckAccountOperation.mm | 7 |
6 files changed, 38 insertions, 3 deletions
diff --git a/src/async/imap/MCIMAPCheckAccountOperation.cpp b/src/async/imap/MCIMAPCheckAccountOperation.cpp index 4a833711..64e9a51a 100644 --- a/src/async/imap/MCIMAPCheckAccountOperation.cpp +++ b/src/async/imap/MCIMAPCheckAccountOperation.cpp @@ -16,11 +16,13 @@ using namespace mailcore; IMAPCheckAccountOperation::IMAPCheckAccountOperation() { mLoginResponse = NULL; + mLoginUnparsedResponseData = NULL; } IMAPCheckAccountOperation::~IMAPCheckAccountOperation() { MC_SAFE_RELEASE(mLoginResponse); + MC_SAFE_RELEASE(mLoginUnparsedResponseData); } void IMAPCheckAccountOperation::main() @@ -31,6 +33,7 @@ void IMAPCheckAccountOperation::main() session()->session()->login(&error); if (error != ErrorNone) { MC_SAFE_REPLACE_COPY(String, mLoginResponse, session()->session()->loginResponse()); + MC_SAFE_REPLACE_COPY(Data, mLoginUnparsedResponseData, session()->session()->unparsedResponseData()); } } setError(error); @@ -40,3 +43,8 @@ String * IMAPCheckAccountOperation::loginResponse() { return mLoginResponse; } + +Data * IMAPCheckAccountOperation::loginUnparsedResponseData() +{ + return mLoginUnparsedResponseData; +} diff --git a/src/async/imap/MCIMAPCheckAccountOperation.h b/src/async/imap/MCIMAPCheckAccountOperation.h index b6ce9dbf..c8d987f3 100644 --- a/src/async/imap/MCIMAPCheckAccountOperation.h +++ b/src/async/imap/MCIMAPCheckAccountOperation.h @@ -22,12 +22,14 @@ namespace mailcore { virtual ~IMAPCheckAccountOperation(); virtual String * loginResponse(); + virtual Data * loginUnparsedResponseData(); public: // subclass behavior virtual void main(); private: String * mLoginResponse; + Data * mLoginUnparsedResponseData; }; } diff --git a/src/core/imap/MCIMAPSession.cpp b/src/core/imap/MCIMAPSession.cpp index 5cee16b1..61be95c3 100644 --- a/src/core/imap/MCIMAPSession.cpp +++ b/src/core/imap/MCIMAPSession.cpp @@ -356,6 +356,7 @@ void IMAPSession::init() mShouldDisconnect = false; mLoginResponse = NULL; mGmailUserDisplayName = NULL; + mUnparsedResponseData = NULL; } IMAPSession::IMAPSession() @@ -365,6 +366,7 @@ IMAPSession::IMAPSession() IMAPSession::~IMAPSession() { + MC_SAFE_RELEASE(mUnparsedResponseData); MC_SAFE_RELEASE(mGmailUserDisplayName); MC_SAFE_RELEASE(mLoginResponse); MC_SAFE_RELEASE(mClientIdentity); @@ -485,6 +487,11 @@ String * IMAPSession::loginResponse() return mLoginResponse; } +Data * IMAPSession::unparsedResponseData() +{ + return mUnparsedResponseData; +} + static bool hasError(int errorCode) { return ((errorCode != MAILIMAP_NO_ERROR) && (errorCode != MAILIMAP_NO_ERROR_AUTHENTICATED) && @@ -716,7 +723,10 @@ void IMAPSession::login(ErrorCode * pError) MCLog("login"); MCAssert(mState == STATE_CONNECTED); - + + MC_SAFE_RELEASE(mLoginResponse); + MC_SAFE_RELEASE(mUnparsedResponseData); + if (mImap->imap_connection_info != NULL) { if (mImap->imap_connection_info->imap_capability != NULL) { mailimap_capability_data_free(mImap->imap_connection_info->imap_capability); @@ -832,6 +842,13 @@ void IMAPSession::login(ErrorCode * pError) else if (r == MAILIMAP_ERROR_PARSE) { mShouldDisconnect = true; * pError = ErrorParse; + + Data * unparsed_response = Data::data(); + if (mImap->imap_stream_buffer != NULL) { + unparsed_response = Data::dataWithBytes(mImap->imap_stream_buffer->str, (unsigned int) mImap->imap_stream_buffer->len); + } + MC_SAFE_REPLACE_RETAIN(Data, mUnparsedResponseData, unparsed_response); + return; } else if (hasError(r)) { diff --git a/src/core/imap/MCIMAPSession.h b/src/core/imap/MCIMAPSession.h index 8b3fed0f..adbecd43 100644 --- a/src/core/imap/MCIMAPSession.h +++ b/src/core/imap/MCIMAPSession.h @@ -209,6 +209,8 @@ namespace mailcore { virtual bool isAutomaticConfigurationEnabled(); virtual String * loginResponse(); + /** Filled by unparsed protocol data in case of ParseError (only for login for now). */ + virtual Data * unparsedResponseData(); public: // private virtual void loginIfNeeded(ErrorCode * pError); @@ -276,6 +278,7 @@ namespace mailcore { String * mLoginResponse; String * mGmailUserDisplayName; + Data * mUnparsedResponseData; void init(); void bodyProgress(unsigned int current, unsigned int maximum); diff --git a/src/objc/abstract/MCOConstants.h b/src/objc/abstract/MCOConstants.h index b2a890ab..8fa4d115 100644 --- a/src/objc/abstract/MCOConstants.h +++ b/src/objc/abstract/MCOConstants.h @@ -461,5 +461,7 @@ typedef void (^MCOOperationQueueRunningChangeBlock)(void); /** MCOIMAPResponseKey is a key for NSError userInfo dictionary, the value is string with the server response. */ #define MCOIMAPResponseKey @"MCOIMAPResponseKey" +/** MCOIMAPUnparsedResponseDataKey is a key for NSError userInfo dictionary, the value is data with the unparsed server response in case of ParseError. */ +#define MCOIMAPUnparsedResponseDataKey @"MCOIMAPUnparsedResponseDataKey" #endif diff --git a/src/objc/imap/MCOIMAPCheckAccountOperation.mm b/src/objc/imap/MCOIMAPCheckAccountOperation.mm index 0c6161c4..0c9f7e51 100644 --- a/src/objc/imap/MCOIMAPCheckAccountOperation.mm +++ b/src/objc/imap/MCOIMAPCheckAccountOperation.mm @@ -62,9 +62,12 @@ typedef void (^CompletionType)(NSError *error); _completionBlock(nil); } else { NSError * error = [NSError mco_errorWithErrorCode:op->error()]; - if (op->loginResponse() != NULL) { + if (op->loginResponse() != NULL || op->loginUnparsedResponseData() != NULL) { NSMutableDictionary * userInfo = [[error userInfo] mutableCopy]; - userInfo[MCOIMAPResponseKey] = MCO_TO_OBJC(op->loginResponse()); + if (op->loginResponse() != NULL) + userInfo[MCOIMAPResponseKey] = MCO_TO_OBJC(op->loginResponse()); + if (op->loginUnparsedResponseData() != NULL) + userInfo[MCOIMAPUnparsedResponseDataKey] = MCO_TO_OBJC(op->loginUnparsedResponseData()); error = [NSError errorWithDomain:[error domain] code:[error code] userInfo:userInfo]; [userInfo release]; } |