Process <status> in multi-get responses without <propstat> (see #475)

This commit is contained in:
Ricki Hirner 2015-04-29 20:04:56 +02:00
parent 1f9b8a296a
commit a13dbb7164
4 changed files with 57 additions and 6 deletions

View file

@ -199,6 +199,17 @@ public class WebDavResourceTest extends InstrumentationTestCase {
for (WebDavResource member : davAddressBook.getMembers())
assertNotNull(member.getContent());
}
public void testMultiGetWith404() throws Exception {
WebDavResource davAddressBook = new WebDavResource(davCollection, "addressbooks/default-with-404.vcf/");
try {
davAddressBook.multiGet(DavMultiget.Type.ADDRESS_BOOK, new String[]{ "notexisting" });
fail();
} catch(NotFoundException e) {
// addressbooks/default.vcf/notexisting doesn't exist,
// so server responds with 404 which causes a NotFoundException
}
}
public void testPutAddDontOverwrite() throws Exception {
// should succeed on a non-existing file

View file

@ -288,6 +288,35 @@ exports.getBodyParts = function(conf) {
}
}),
/* address-book multiget where one resource has 404 Not Found */
new RoboHydraHeadDAV({
path: "/dav/addressbooks/default-with-404.vcf/",
handler: function(req,res,next) {
if (req.method == "REPORT" && req.rawBody.toString().match(/addressbook-multiget[\s\S]+<prop>[\s\S]+<href>/m &&
req.rawBody.toString().match(/<href>\/dav\/addressbooks\/default-with-404\.vcf\/notexisting<\/href>/m))) {
res.statusCode = 207;
res.write('\<?xml version="1.0" encoding="utf-8" ?>\
<multistatus xmlns="DAV:" xmlns:CARD="urn:ietf:params:xml:ns:carddav">\
<response>\
<href>/dav/addressbooks/default-with-404.vcf</href>\
<propstat>\
<prop>\
<resourcetype><collection/></resourcetype>\
</prop>\
<status>HTTP/1.1 200 OK</status>\
</propstat>\
</response>\
<response>\
<href>/dav/addressbooks/default-with-404.vcf/notexisting</href>\
<status>HTTP/1.1 404 Not Found</status>\
</response>\
</multistatus>\
');
}
}
}),
]
};
};

View file

@ -18,8 +18,11 @@ import lombok.Getter;
@Root(strict=false)
public class DavResponse {
@Element
@Getter DavHref href;
DavHref href;
@ElementList(inline=true)
@Getter List<DavPropstat> propstat;
@Element(required=false)
String status;
@ElementList(inline=true,required=false)
List<DavPropstat> propstat;
}

View file

@ -419,7 +419,10 @@ public class WebDavResource {
throw new HttpException(code, reason);
}
}
/**
* Process a 207 Multi-status response as defined in RFC 4918 "13. Multi-Status Response"
*/
protected void processMultiStatus(HttpResponse response) throws IOException, HttpException, DavException {
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_MULTI_STATUS)
throw new DavNoMultiStatusException();
@ -447,7 +450,7 @@ public class WebDavResource {
for (DavResponse singleResponse : multiStatus.response) {
URI href;
try {
href = location.resolve(URIUtils.parseURI(singleResponse.getHref().href, false));
href = location.resolve(URIUtils.parseURI(singleResponse.href.href, false));
} catch(Exception ex) {
Log.w(TAG, "Ignoring illegal member URI in multi-status response", ex);
continue;
@ -459,7 +462,12 @@ public class WebDavResource {
List<String> supportedComponents = null;
byte[] data = null;
for (DavPropstat singlePropstat : singleResponse.getPropstat()) {
// in <response>, either <status> or <propstat> must be present
if (singleResponse.status != null) { // method 1 (status of resource as a whole)
StatusLine status = BasicLineParserHC4.parseStatusLine(singleResponse.status, new BasicLineParserHC4());
checkResponse(status);
} else for (DavPropstat singlePropstat : singleResponse.propstat) { // method 2 (propstat)
StatusLine status = BasicLineParserHC4.parseStatusLine(singlePropstat.status, new BasicLineParserHC4());
// ignore information about missing properties etc.