Closed MrNoodle closed 9 years ago
-createDirectory:... does work when setting the flag to create intermediate directories, btw.
Having a look through the code, I think this is a non-standard-compliant server. What sort is the server you're using?
Our current implementation appears to go:
405
, create the intermediate directoriesSo it looks like the server you're working with instead returns a 404
, and so our implementation gives up.
I don't control the server so I don't know. It's mydrive.ch. You can create a free account there and try it yourself.
I guess -createDirectory.. does something different? My current workaround I have in place is to do a createDirectory first and that seems to work.
-createDirectory…
doesn't do anything different. The fallback in step 2 is actually to call that method!
Could you grab me a transcript at all, to confirm my hypothesis?
Transcript below. Note that the dir "testsubdir" is the intermediate dir that should be created. The source file does exist. Maybe the bug is on the local end though?
2014-10-07 10:19:50.519 xctest[74052:802f] <?xml version="1.0" encoding="utf-8"?>
<d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns"><d:response><d:href>/test/74052-uploadtest/</d:href><d:propstat><d:prop><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Tue, 07 Oct 2014 14:18:10 +0000</d:getlastmodified><d:resourcetype><d:collection/></d:resourcetype></d:prop><d:status>HTTP/1.1 200 Ok</d:status></d:propstat></d:response><d:response><d:href>/test/74052-uploadtest/testfile</d:href><d:propstat><d:prop><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Tue, 07 Oct 2014 14:18:12 +0000</d:getlastmodified><d:getcontentlength>0</d:getcontentlength><d:resourcetype/><d:getetag>"fb366885ad57123e021cc62443f3cfcc8b6b24b2"</d:getetag><d:getcontenttype>application/x-empty</d:getcontenttype></d:prop><d:status>HTTP/1.1 200 Ok</d:status></d:propstat></d:response><d:response><d:href>/test/74052-uploadtest/testfile-1</d:href><d:propstat><d:prop><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Tue, 07 Oct 2014 14:18:14 +0000</d:getlastmodified><d:getcontentlength>0</d:getcontentlength><d:resourcetype/><d:getetag>"ec958ad59d3cefd664da716561298135ca7edc9f"</d:getetag><d:getcontenttype>application/x-empty</d:getcontenttype></d:prop><d:status>HTTP/1.1 200 Ok</d:status></d:propstat></d:response><d:response><d:href>/test/74052-uploadtest/testsubfile</d:href><d:propstat><d:prop><d:getlastmodified xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" b:dt="dateTime.rfc1123">Tue, 07 Oct 2014 14:19:10 +0000</d:getlastmodified><d:getcontentlength>0</d:getcontentlength><d:resourcetype/><d:getetag>"b279144ef46fd876aac11765fb2335d90fc94bce"</d:getetag><d:getcontenttype>application/x-empty</d:getcontenttype></d:prop><d:status>HTTP/1.1 200 Ok</d:status></d:propstat></d:response></d:multistatus>
2014-10-07 10:19:50.956 xctest[74052:303] Error uploading item from file:///XXXXXXXXXXXXXXXX/testdir/testsubdir/testsubfile to https://XXXXXXXXX@webdav.mydrive.ch/test/74052-uploadtest/testsubdir/testsubfile: Error Domain=NSCocoaErrorDomain Code=4 "The file “testsubfile” could not be uploaded. The file doesn’t exist." UserInfo=0x10818d890 {NSLocalizedDescription=The file “testsubfile” could not be uploaded. The file doesn’t exist., NSUnderlyingError=0x10818d0a0 "The operation couldn’t be completed. not found"}
I'm a little puzzled. Is the <d:multistatus …
XML the data you receive back from the server in the event of an upload failure?
Actually, it seems that's from code leading up to the upload itself where it gets directory listings. Apparently, there are no transcripts of the upload which reinforces the idea that it's on the local end.
It may be claiming the source file isn't present.
source url: file:///XXXXXXXXXX/74388-uploadtest/testdir/testsubdir/testsubfile destination url: https://XXXXX@webdav.mydrive.ch/test/74388-uploadtest/testsubdir/testsubfile
"testsubfile" does exist on the local drive as does "/test/74388-uploadtest" on the server. "testsubdir" is the intermediate directory that is to be created.
But in which case, where does the 404
at the top of this case come from?! I think the best thing if you can report this is to work your way through -[CKWebDAVProtocol initForCreatingFileWithRequest:…]
to spot where something unexpected happens.
That may be from my rollback code after the upload. My latest run where I stepped through and specifically watched the output, I only performed the upload code and nothing was output to the transcript.
Right, so can you step through in the debugger to hunt it down?
Ok, tracing through it, it does indeed get a 404 in response, which I'm guessing the server does because the intermediate directory is missing. I do see the code in response to the 409.
So, do we change the implementation to handle 404 similarly? My workaround of doing a create first does work so I can leave that in though it would be nice if this was supported further down.
My inclination is to be lenient and treat 404
codes the same as 405
. Sure it's not to spec, but it does seem a reasonable thing to return.
One other aspect to watch out for though: WebDAV is forced to handle this case by uploading the file, and then if that fails, it needs to make the directories, and do the upload again. If the file is rather large, that could be quite a waste of time and bandwidth. It might be in your interest to perform directory creation first, to avoid that anyway.
Interesting. So, I'll keep my workaround in place anyways. It's efficient since in my pre-flighting, I'm checking for the existence of directories up to the file itself so I only do it if the directories are missing.
This might have broken at some point recently as I'm pretty sure it was working before. Get the following response (using WebDAV) when uploading a file with some non-existent intermediate directories. Everything up to "testsubdir" exists:
Error Domain=org.w3.http Code=404 "The operation couldn’t be completed. not found" UserInfo=0x10071a170 {NSLocalizedFailureReason=not found, response=<NSHTTPURLResponse: 0x10071a9e0> { URL: https://XXXXXXXXXXX/test/39744-uploadtest/testsubdir/testsubfile } { status code: 404, headers { Connection = close; "Content-Encoding" = gzip; "Content-Length" = 20; "Content-Type" = "text/html"; Date = "Mon, 06 Oct 2014 00:48:54 GMT"; Server = "Apache/2.2.16 (Debian)"; Vary = "Accept-Encoding"; } }}