Commit ee2900e3 authored by Dennis Schridde's avatar Dennis Schridde Committed by Daniel Vrátil
Browse files

Idempotent CREATE and DELETE

If CREATE fails with an ALREADYEXISTS response code, that is not an error
since the intended result (the object existing at the target location)
has been achieved.

Likewise, if DELETE fails with an NONEXISTENT response code, that is
not an error since the intended result (the object being gone from
the target location) has been achieved.

Please note that for RENAME response code ALREADYEXISTS *is* an error
since the content of the source folder was not moved as intended.

cf. https://tools.ietf.org/html/rfc5530#section-3

BUG: 423672
parent 1c83e7c6
......@@ -42,6 +42,33 @@ void CreateJob::doStart()
d->tags << d->sessionInternal()->sendCommand("CREATE", '\"' + KIMAP::encodeImapFolderName(d->mailBox.toUtf8()) + '\"');
}
void CreateJob::handleResponse(const Response &response)
{
Q_D(CreateJob);
if (!response.content.isEmpty() &&
d->tags.contains(response.content.first().toString())) {
if (response.content.size() >= 2 &&
response.content[1].toString() == "NO") {
for (auto it = response.responseCode.cbegin(), end = response.responseCode.cend();
it != end; ++it) {
// ALREADYEXISTS can be considered a success during CREATE
// cf. https://tools.ietf.org/html/rfc5530#section-3
if (it->toString() == "ALREADYEXISTS") {
// Code copied from handleErrorReplies:
d->tags.removeAll(response.content.first().toString());
if (d->tags.isEmpty()) { // Only emit result when the last command returned
emitResult();
}
return;
}
}
}
}
handleErrorReplies(response);
}
void CreateJob::setMailBox(const QString &mailBox)
{
Q_D(CreateJob);
......
......@@ -57,6 +57,7 @@ public:
protected:
void doStart() override;
void handleResponse(const Response &response) override;
};
}
......
......@@ -42,6 +42,33 @@ void DeleteJob::doStart()
d->tags << d->sessionInternal()->sendCommand("DELETE", '\"' + KIMAP::encodeImapFolderName(d->mailBox.toUtf8()) + '\"');
}
void DeleteJob::handleResponse(const Response &response)
{
Q_D(DeleteJob);
if (!response.content.isEmpty() &&
d->tags.contains(response.content.first().toString())) {
if (response.content.size() >= 2 &&
response.content[1].toString() == "NO") {
for (auto it = response.responseCode.cbegin(), end = response.responseCode.cend();
it != end; ++it) {
// NONEXISTENT can be considered a success during DELETE
// cf. https://tools.ietf.org/html/rfc5530#section-3
if (it->toString() == "NONEXISTENT") {
// Code copied from handleErrorReplies:
d->tags.removeAll(response.content.first().toString());
if (d->tags.isEmpty()) { // Only emit result when the last command returned
emitResult();
}
return;
}
}
}
}
handleErrorReplies(response);
}
void DeleteJob::setMailBox(const QString &mailBox)
{
Q_D(DeleteJob);
......
......@@ -53,6 +53,7 @@ public:
protected:
void doStart() override;
void handleResponse(const Response &response) override;
};
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment