Search code examples
ioscore-datasynchronizationwebdavensembles

IIS webdav and Ensembles


I'm trying to use sync through an IIS 8 Webdav backend with Ensembles. The problem i encounter is that the first sync works fine, but when i try to sync a second time or on a second unit (iPad in this case) I get a server error 405 "method not allowed". Has anyone encountered this and got it working, to sync with IIS Webdav?

This is the allheaderfield property of the server response:

" UserInfo={NSLocalizedDescription=HTTP status code was {
    Allow = "COPY, PROPFIND, DELETE, MOVE, PROPPATCH, LOCK, UNLOCK";
    Connection = "Keep-Alive";
    "Content-Length" = 1293;
    "Content-Type" = "text/html";
    Date = "Mon, 25 Jan 2016 12:02:07 GMT";
    "Persistent-Auth" = true;
    Server = "Microsoft-IIS/8.5";
    "X-UA-Compatible" = "IE=8";

EDIT: It might be possible that this isn't a configuration problem after all. I added a few logs and the createDirectoryAtPath method gives me HTTP error 405, this is the original code:

- (void)createDirectoryAtPath:(NSString *)path completion:(CDECompletionBlock)completion{
NSMutableURLRequest *request = [self mutableURLRequestForPath:path];
request.HTTPMethod = @"MKCOL";
[request setValue:@"application/xml" forHTTPHeaderField:@"Content-Type"];

[self sendURLRequest:request completion:^(NSError *error, NSInteger statusCode, NSData *responseData) {
    if (completion) completion(error);
}];}

And this is the directoryExistsAtPath method:

- (void)directoryExistsAtPath:(NSString *)path completion:(CDEDirectoryExistenceCallback)completion{
[self sendPropertyFindRequestForPath:path depth:0 completion:^(NSError *error, NSInteger statusCode, NSData *responseData) {
    if (error && statusCode != 404) {
        if (completion) completion(NO, error);
    }
    else if (statusCode == 404) {
        if (completion) completion(NO, nil);
    }
    else {
        CDEWebDavResponseParser *parser = [[CDEWebDavResponseParser alloc] initWithData:responseData];
        BOOL succeeded = [parser parse:&error];
        if (!succeeded) {
            if (completion) completion(NO, error);
            return;
        }

        BOOL isDir = [parser.cloudItems.lastObject isKindOfClass:[CDECloudDirectory class]];
        if (completion) completion(isDir, nil);
    }
}];}

If i replace the first parameter (currently the isDir-variable) in the completion block at the end to YES, the 405 error does not appear.On logging the parser.clouditems.lastobject, I find that it is often (or always?) empty). So setting the parameter to YES, results in data being uploaded to my webdav, and the folders are in place. However, testing on a second unit (or reinstalling the app on the same unit), download never happens - the downloadFromPath never gets called, a "GET"-request is never sent.

Looking at the calling code in the underlying framework (CDECloudmanager mostly) hasn't led me anywhere so far.

As the directoryExistsAtPath is optional, i tried commenting it out, but i don't think it made a difference.

Another thing I noticed is that I get several baseline files in the baselines folder. According to the Ensembles documentation, there should only be one.

Any clues?


Solution

  • Ok seems I got this working at last. I had to make a change in the CDEWebDavCloudFileSystem class to avoid the 405 error. Doing that however, I encountered a 404 error. That one was solved by configuring the IIS webdav.

    So step 1, I changed the request in the sendPropertyFindRequestForPath method:

    new code:

    static NSString *xml = @"<?xml version=\"1.0\" encoding=\"utf-8\" ?><D:propfind xmlns:D=\"DAV:\"><D:allprop/></D:propfind>";
    

    original code:

    static NSString *xml = @"<?xml version=\"1.0\" encoding=\"utf-8\" ?><D:propfind xmlns:D=\"DAV:\"><D:prop><D:href/><D:resourcetype/><D:creationdate/><D:getlastmodified/><D:getcontentlength/><D:response/></D:prop></D:propfind>";

    To remove the 404 error appearing after that I had to add mime type application/xml to the .cdeevent extension.

    This link goes into detail of how to configure IIS for that:

    http://anandthearchitect.com/2013/08/01/webdav-404file-or-directory-not-found/