diff --git a/AndroidManifest.xml b/AndroidManifest.xml index dc3eea5c..b2954544 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,8 +1,8 @@ + android:versionCode="13" + android:versionName="0.4-alpha" > " + url); + Log.w(TAG, "Trying to repair invalid URL: " + original + " -> " + url); return url; } } diff --git a/src/at/bitfire/davdroid/webdav/DavMultiget.java b/src/at/bitfire/davdroid/webdav/DavMultiget.java index 97adaafd..e80897b8 100644 --- a/src/at/bitfire/davdroid/webdav/DavMultiget.java +++ b/src/at/bitfire/davdroid/webdav/DavMultiget.java @@ -11,7 +11,9 @@ import java.util.List; import org.simpleframework.xml.Element; import org.simpleframework.xml.ElementList; +import org.simpleframework.xml.Order; +@Order(elements={"prop","href"}) public class DavMultiget { @Element DavProp prop; diff --git a/src/at/bitfire/davdroid/webdav/WebDavResource.java b/src/at/bitfire/davdroid/webdav/WebDavResource.java index 4d00d1af..5b6a935d 100644 --- a/src/at/bitfire/davdroid/webdav/WebDavResource.java +++ b/src/at/bitfire/davdroid/webdav/WebDavResource.java @@ -286,7 +286,7 @@ public class WebDavResource { return false; } - public boolean multiGet(String[] names, MultigetType type) throws IOException, InvalidDavResponseException, HttpException { + public void multiGet(String[] names, MultigetType type) throws IOException, InvalidDavResponseException, HttpException { DavMultiget multiget = (type == MultigetType.ADDRESS_BOOK) ? new DavAddressbookMultiget() : new DavCalendarMultiget(); multiget.prop = new DavProp(); @@ -305,9 +305,9 @@ public class WebDavResource { StringWriter writer = new StringWriter(); try { serializer.write(multiget, writer); - } catch (Exception e) { - Log.e(TAG, e.getLocalizedMessage()); - return false; + } catch (Exception ex) { + Log.e(TAG, "Couldn't create XML multi-get request", ex); + throw new InvalidDavResponseException(); } HttpReport report = new HttpReport(location, writer.toString()); @@ -322,15 +322,14 @@ public class WebDavResource { multistatus = serializer.read(DavMultistatus.class, is, false); Log.d(TAG, "Received multistatus response: " + baos.toString("UTF-8")); - } catch (Exception e) { - Log.e(TAG, e.getLocalizedMessage()); - return false; + } catch (Exception ex) { + Log.e(TAG, "Couldn't parse multi-get response", ex); + throw new InvalidDavResponseException(); } processMultiStatus(multistatus); } else throw new InvalidDavResponseException(); - return true; } @@ -390,6 +389,7 @@ public class WebDavResource { Log.w(TAG, "Ignoring illegal member URI in multi-status response", ex); continue; } + Log.d(TAG, "Processing multi-status element: " + href); // about which resource is this response? WebDavResource referenced = null; diff --git a/test/robohydra/plugins/dav-default/index.js b/test/robohydra/plugins/dav-default/index.js index 1c9b99fb..37102494 100644 --- a/test/robohydra/plugins/dav-default/index.js +++ b/test/robohydra/plugins/dav-default/index.js @@ -155,7 +155,52 @@ exports.getBodyParts = function(conf) { } else if (req.method == "DELETE") res.statusCode = 204; } - }) + }), + + /* address-book multiget */ + new RoboHydraHeadDAV({ + path: "/dav/addressbooks/default.vcf/", + handler: function(req,res,next) { + if (req.method == "REPORT" && req.rawBody.toString().match(/addressbook-multiget[\s\S]+[\s\S]+/m)) { + res.statusCode = 207; + res.write('\\ + \ + \ + /dav/addressbooks/default.vcf/1.vcf\ + \ + \ + \ + BEGIN:VCARD\ + VERSION:3.0\ + NICKNAME:MULTIGET1\ + UID:1\ + END:VCARD\ + \ + \ + HTTP/1.1 200 OK\ + \ + \ + \ + /dav/addressbooks/default.vcf/2.vcf\ + \ + \ + \ + BEGIN:VCARD\ + VERSION:3.0\ + NICKNAME:MULTIGET2\ + UID:2\ + END:VCARD\ + \ + \ + HTTP/1.1 200 OK\ + \ + \ + \ + '); + } + } + }), + ] }; }; diff --git a/test/src/at/bitfire/davdroid/webdav/test/WebDavResourceTest.java b/test/src/at/bitfire/davdroid/webdav/test/WebDavResourceTest.java index d094e3e5..20ecfa8a 100644 --- a/test/src/at/bitfire/davdroid/webdav/test/WebDavResourceTest.java +++ b/test/src/at/bitfire/davdroid/webdav/test/WebDavResourceTest.java @@ -11,9 +11,11 @@ import org.apache.http.HttpException; import android.content.res.AssetManager; import android.test.InstrumentationTestCase; import at.bitfire.davdroid.webdav.HttpPropfind; +import at.bitfire.davdroid.webdav.InvalidDavResponseException; import at.bitfire.davdroid.webdav.NotFoundException; import at.bitfire.davdroid.webdav.PreconditionFailedException; import at.bitfire.davdroid.webdav.WebDavResource; +import at.bitfire.davdroid.webdav.WebDavResource.MultigetType; import at.bitfire.davdroid.webdav.WebDavResource.PutMode; // tests require running robohydra! @@ -142,6 +144,15 @@ public class WebDavResourceTest extends InstrumentationTestCase { )); } + public void testMultiGet() throws InvalidDavResponseException, IOException, HttpException { + WebDavResource davAddressBook = new WebDavResource(davCollection, "addressbooks/default.vcf", true); + davAddressBook.multiGet(new String[] { "1.vcf", "2.vcf" }, MultigetType.ADDRESS_BOOK); + assertEquals(2, davAddressBook.getMembers().size()); + for (WebDavResource member : davAddressBook.getMembers()) { + assertNotNull(member.getContent()); + } + } + public void testPutAddDontOverwrite() throws IOException, HttpException { // should succeed on a non-existing file davNonExistingFile.put(SAMPLE_CONTENT, PutMode.ADD_DONT_OVERWRITE);