Commit ff465bda authored by chriadam's avatar chriadam

[buteo-sync-plugin-carddav] Allow sync of non .vcf resources. Contributes to MER#1863

Previously, we only synced resources returned by the server in
response to an etags request, if those resources ended in ".vcf".

This commit modifies the behaviour so that we assume that any resource
which has a suffix which is not ".vcf" (e.g., ".ics" or ".eml") should
be ignored, but other resources without a suffix should be synced.

This allows us to sync in cases where the remote resource is found at
a path like "/carddav/Addressbooks/personal/johnsmith" rather than
a path like "/carddav/Addressbooks/personal/johnsmith.vcf".

Contributes to MER#1863
parent e30631b1
......@@ -65,6 +65,7 @@ This package contains unit tests for the CardDAV Buteo sync plugin.
/opt/tests/buteo/plugins/carddav/data/replyparser_synctokendelta_single-well-formed-addition.xml
/opt/tests/buteo/plugins/carddav/data/replyparser_contactmetadata_empty.xml
/opt/tests/buteo/plugins/carddav/data/replyparser_contactmetadata_single-well-formed-add-mod-rem-unch.xml
/opt/tests/buteo/plugins/carddav/data/replyparser_contactmetadata_single-vcf-and-non-vcf.xml
/opt/tests/buteo/plugins/carddav/data/replyparser_contactdata_empty.xml
/opt/tests/buteo/plugins/carddav/data/replyparser_contactdata_single-well-formed.xml
/opt/tests/buteo/plugins/carddav/data/replyparser_contactdata_single-hs-utc-iso8601-bday.xml
......
......@@ -506,9 +506,17 @@ QList<ReplyParser::ContactInformation> ReplyParser::parseSyncTokenDelta(const QB
status = rmap.value("status").toMap().value("@text").toString();
}
if (status.contains(QLatin1String("200 OK"))) {
if (!currInfo.uri.endsWith(QStringLiteral(".vcf"), Qt::CaseInsensitive)) {
if (currInfo.uri.endsWith(QChar('/'))) {
// this is probably a response for the addressbook resource,
// rather than for a contact resource within the addressbook.
LOG_DEBUG(Q_FUNC_INFO << "ignoring non-contact (addressbook?) resource:" << currInfo.uri << currInfo.etag << status);
continue;
} else if (currInfo.uri.length() > 5
&& (currInfo.uri.at(currInfo.uri.length()-4) == QChar('.')
|| currInfo.uri.at(currInfo.uri.length()-3) == QChar('.'))
&& !currInfo.uri.endsWith(QStringLiteral(".vcf"), Qt::CaseInsensitive)) {
// the uri has a file suffix like .ics or .eml rather than .vcf.
// this is probably not a contact resource, but instead some other file reported erroneously.
LOG_DEBUG(Q_FUNC_INFO << "ignoring non-contact resource:" << currInfo.uri << currInfo.etag << status);
continue;
}
......@@ -582,12 +590,22 @@ QList<ReplyParser::ContactInformation> ReplyParser::parseContactMetadata(const Q
if (status.isEmpty()) {
status = rmap.value("status").toMap().value("@text").toString();
}
if (!currInfo.uri.endsWith(QStringLiteral(".vcf"), Qt::CaseInsensitive)) {
if (currInfo.uri.endsWith(QChar('/'))) {
// this is probably a response for the addressbook resource,
// rather than for a contact resource within the addressbook.
LOG_DEBUG(Q_FUNC_INFO << "ignoring non-contact (addressbook?) resource:" << currInfo.uri << currInfo.etag << status);
continue;
} else if (currInfo.uri.length() > 5
&& (currInfo.uri.at(currInfo.uri.length()-4) == QChar('.')
|| currInfo.uri.at(currInfo.uri.length()-3) == QChar('.'))
&& !currInfo.uri.endsWith(QStringLiteral(".vcf"), Qt::CaseInsensitive)) {
// the uri has a file suffix like .ics or .eml rather than .vcf.
// this is probably not a contact resource, but instead some other file reported erroneously.
LOG_DEBUG(Q_FUNC_INFO << "ignoring non-contact resource:" << currInfo.uri << currInfo.etag << status);
continue;
}
QMap<QString, QString>::const_iterator it = q->m_contactUris.constBegin();
for ( ; it != q->m_contactUris.constEnd(); ++it) {
if (it.value() == currInfo.uri) {
......
......@@ -359,6 +359,9 @@ QNetworkReply *RequestGenerator::contactMultiget(const QString &serverUrl, const
}
if (uri.endsWith(QStringLiteral(".vcf")) && uri.startsWith(addressbookPath)) {
uriHrefs.append(QStringLiteral("<d:href>%1</d:href>").arg(href));
} else if (uri.startsWith(addressbookPath)) {
// contact resource which doesn't end in .vcf but is otherwise well-formed / fully specified.
uriHrefs.append(QStringLiteral("<d:href>%1</d:href>").arg(href));
} else {
uriHrefs.append(QStringLiteral("<d:href>%1/%2.vcf</d:href>").arg(addressbookPath).arg(href));
}
......
<d:multistatus xmlns:d="DAV:" xmlns:card="urn:ietf:params:xml:ns:carddav">
<d:response>
<d:href>/addressbooks/johndoe/contacts/new.vcf</d:href>
<d:propstat>
<d:prop>
<d:getetag>"0021-0021"</d:getetag> <!-- new uri/etag :. added -->
</d:prop>
<d:status>HTTP/1.1 200 OK</d:status>
</d:propstat>
</d:response>
<d:response>
<d:href>/addressbooks/johndoe/contacts/alsonew</d:href>
<d:propstat>
<d:prop>
<d:getetag>"0022-0022"</d:getetag> <!-- new uri/etag :. added -->
</d:prop>
<d:status>HTTP/1.1 200 OK</d:status>
</d:propstat>
</d:response>
</d:multistatus>
......@@ -425,6 +425,27 @@ void tst_replyparser::parseContactMetadata_data()
<< mContactUris
<< mContactEtags
<< infos;
infos.clear();
mContactUris.clear();
mContactEtags.clear();
ReplyParser::ContactInformation c5;
c5.modType = ReplyParser::ContactInformation::Addition;
c5.uri = QStringLiteral("/addressbooks/johndoe/contacts/new.vcf");
c5.guid = QString();
c5.etag = QStringLiteral("\"0021-0021\"");
ReplyParser::ContactInformation c6;
c6.modType = ReplyParser::ContactInformation::Addition;
c6.uri = QStringLiteral("/addressbooks/johndoe/contacts/alsonew");
c6.guid = QString();
c6.etag = QStringLiteral("\"0022-0022\"");
infos << c5 << c6;
QTest::newRow("two contact additions with vcf and non-vcf extenions in well-formed sync token delta response")
<< QStringLiteral("data/replyparser_contactmetadata_single-vcf-and-non-vcf.xml")
<< QStringLiteral("/addressbooks/johndoe/contacts/")
<< mContactUris
<< mContactEtags
<< infos;
}
void tst_replyparser::parseContactMetadata()
......
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