aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Dmitry Isaikin <isaikin-dmitry@yandex.ru>2016-05-19 20:58:38 +0400
committerGravatar HoĆ  V. DINH <dinh.viet.hoa@gmail.com>2016-05-19 09:58:38 -0700
commit6ea3534c94ced99a10682916c2718be8b93056da (patch)
treeea797cad294800cef0ca4a3b03dbc72230894c47
parent6a720fd8bf82d6220330f148ca8ad351b690a9fd (diff)
Store last server response on login command in case of parse error (#1436)
-rw-r--r--src/async/imap/MCIMAPCheckAccountOperation.cpp8
-rw-r--r--src/async/imap/MCIMAPCheckAccountOperation.h2
-rw-r--r--src/core/imap/MCIMAPSession.cpp19
-rw-r--r--src/core/imap/MCIMAPSession.h3
-rw-r--r--src/objc/abstract/MCOConstants.h2
-rw-r--r--src/objc/imap/MCOIMAPCheckAccountOperation.mm7
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];
}