setName (File and Directory)

68 views
Skip to first unread message

matt.s...@googlemail.com

unread,
Feb 11, 2009, 7:22:57 AM2/11/09
to SabreDAV Discussion

Hi,

Reading this page:
http://code.google.com/p/sabredav/wiki/VirtualFilesystems

And then implementing a simple File + Directory system as described.

class MyFile extends Sabre_DAV_File {
and
class MyDirectory extends Sabre_DAV_Directory {

However, I can never rename files or directories. The setName methods
I've implemented are never called on any of my "MyDirectory" or
"MyFile" objects. Every rename attempt simply comes back with a
message about how the name I've chosen already exists (I presume this
is my DAV client, WebDrive on XP, interpretting the error message from
Sabre).

Am I making an obvious error here?

Thanks,

Matt

Evert Pot

unread,
Feb 11, 2009, 10:34:07 AM2/11/09
to sabredav...@googlegroups.com

The example is actually missing the setName function. You will have to
implement that one yourself.

If you did, there's 2 bits of information I'd need to further figure
out what could have gone wrong:

* the actual code in your classes
* a saved session from charles (http://charlesproxy.com/)

Evert

matt.s...@googlemail.com

unread,
Feb 11, 2009, 11:00:44 AM2/11/09
to SabreDAV Discussion
Thanks Evert.

The code and a Charles session are here:-
http://spandex.dreamhosters.com/SabreDebug/

As is probably obvious, I've got a class that wraps up filesystem-like
commands for accessing a web-app. There's also a "FakeSession" object
in there, which does the authorisation.

The Charles log shows what happens when I try to rename a file (/Sales
toolkit/Sales/Hertz Fonts/Dance.pdf -> Dancer.pdf). It does a lot of
PROPFINDs, but doesn't actually attempt a rename as far as I can tell
(thought the client allows me to get as far as choosing a new name,
before failing).

There's also a "debug" function in there, which logs to the webapp.
The debug function is tested and working, and so I know the setName
function is never being called.

Your help is greatly appreciated. I'd been suffering with another PHP
WebDAV class until I found Sabre yesterday, and I've made more
progress in the last 24 hours than I did in the last week!

Regards,

Matt

matt.s...@googlemail.com

unread,
Feb 11, 2009, 11:05:37 AM2/11/09
to SabreDAV Discussion

> The Charles log shows what happens when I try to rename a file (/Sales
> toolkit/Sales/Hertz Fonts/Dance.pdf -> Dancer.pdf).  It does a lot of
> PROPFINDs, but doesn't actually attempt a rename as far as I can tell
> (thought the client allows me to get as far as choosing a new name,
> before failing).

I should add that I *can* write to the file. e.g. I can copy a
different file over it and everything works correctly. It just
doesn't seem to even *attempt* the rename.

Matt

Evert Pot

unread,
Feb 11, 2009, 11:30:58 AM2/11/09
to sabredav...@googlegroups.com

Very odd indeed! I'm seeing the exact same thing. On thing I do notice
is that webdrive requests a bunch of non-standard properties using
PROPFIND, which leads me to believe there's probably some
incompatibilities.

As far as I can tell sabredav is behaving exactly as it should. A bug
within PROPFIND has been found though since 0.5, so perhaps giving the
trunk version a shot might help.

If that doesn't solve the issue, I can see if I can find some time
tonight to do some testing. I noticed they have a trail, so I can see
mod_dav and perhaps find out that does work and find the differences.

I'd also want to point out that Windows has built-in webdav support
and there's no need for external software to use it.

Sorry I can't be of more help right now!
Evert


matt.s...@googlemail.com

unread,
Feb 11, 2009, 11:42:39 AM2/11/09
to SabreDAV Discussion

> Sorry I can't be of more help right now!

It's been really helpful just explaining it to someone else already.

I found a bug (in my code) that goes some way to explaining it.. I was
checking for the existence of the parent folder when checking if a dir/
file exists.. so it was always succeeding.

i.e. I had
$path = $this->myPath . '/' . $name;

Then...

if (!$this->Proxy->file_exists($this->myPath) throw new [...]

Instead of

if (!$this->Proxy->file_exists($path)) throw new [...]

It does at least attempt the move now.. it's still failing but I'm one
stage further on.

Thanks for your time.

Matt

Evert Pot

unread,
Feb 11, 2009, 11:58:48 AM2/11/09
to sabredav...@googlegroups.com

Great! I'm very curious if there's any other oddities around Webdrive.
Do report back :)

Evert

matt.s...@googlemail.com

unread,
Feb 11, 2009, 12:54:49 PM2/11/09
to SabreDAV Discussion

> Great! I'm very curious if there's any other oddities around Webdrive.
> Do report back :)

I'm seeing WebDrive make a PROPFIND request for the target name, and
now that it doesn't exist, it's getting an exception
(Sabre_DAV_FileNotFoundException, as thrown in the example code and my
code derived from it).. it obviously sees this exception as "Dest file
doesn't exist, safe to move", and then goes on to make a MOVE
request. But this MOVE request gets the same exception, thrown in
exactly the same place, presumably because it's also checking for the
existence of a conflicting destination filename. It then makes
another move request that throws a conflict exception... indicating
that the previous request possibly succeeded to some extent?

I've tried returning null or false from getChild instead of throwing
an exception. In this case successfully copies the file to the new
name rather than renaming it. It does the same for directories
(copying only the directory, not its contents).

I'm going to go test on OSX and Windows builtin clients now and see if
I can determine how much of this is WebDrive.

Regards,

Matt

matt.s...@googlemail.com

unread,
Feb 11, 2009, 12:55:52 PM2/11/09
to SabreDAV Discussion

> I'm seeing WebDrive make a PROPFIND request for the target name, and
> now that it doesn't exist, it's getting an exception

Forgot to say, there's a 2nd Charles session at
http://spandex.dreamhosters.com/SabreDebug/

Evert Pot

unread,
Feb 11, 2009, 1:20:51 PM2/11/09
to sabredav...@googlegroups.com
The error is triggered at:

123: $destination = $destinationParent->getChild($destinationName);

However, this directory was just created at

121: $destinationParent->createDirectory($destinationName);

This could mean two things:

* the directory was not created.
* somehow you're affected by the statcache, check www.php.net/clearstatcache()
;

Also:

The second MOVE has this as a destination:
http://filestorematt.worktribedev.com:80http://filestorematt.worktribedev.com/Sales%20toolkit/Sales/Hertz%20Faaonts

A bit odd, at least :)

Evert

matt.s...@googlemail.com

unread,
Feb 11, 2009, 6:21:40 PM2/11/09
to SabreDAV Discussion
> The second MOVE has this as a destination:http://filestorematt.worktribedev.com:80http://filestorematt.worktrib...
>
> A bit odd, at least :)

Very strange. And yet it's *still* better than the builtin windows
client :)

Everything looking good on this now. Works on WebDrive and OSX
builtin client. Passes litmus tests too.

Main problems were, of course, my bugs and me failing to understand
how Sabre works :)

I also found it useful to extend Sabre_DAV_ObjectTree and implement
"move" directly as it seems that it actually does a "copy then delete"
on file/directory objects by default... whereas genuine "move"
operations are MUCH cheaper than copy+delete in my Virtual filesystem.

Regards,

Matt

Evert Pot

unread,
Feb 11, 2009, 6:41:34 PM2/11/09
to sabredav...@googlegroups.com
> Everything looking good on this now. Works on WebDrive and OSX
> builtin client. Passes litmus tests too.
>
> Main problems were, of course, my bugs and me failing to understand
> how Sabre works :)
>
> I also found it useful to extend Sabre_DAV_ObjectTree and implement
> "move" directly as it seems that it actually does a "copy then delete"
> on file/directory objects by default... whereas genuine "move"
> operations are MUCH cheaper than copy+delete in my Virtual filesystem.

If your back-end allows it, it's definitely recommended to override
both copy and move. They will generally be quite slow.

I personally have a mixed backend, which kinda looks like this :

Project1
Templates - database backed
- template1 - database backed
Assets - filesystem backed

For me it would be an option to check if a move or copy operation
happens solely within the 'assets' sub-tree, and let the filesystem
handle it, and otherwise fall back on the much slower version. Haven't
felt like doing that though :)

I've also been contemplating adding a new node-type next to Node/File/
Directory which would be 'Tree'. Whenever the ObjectTree comes across
one, it could delegate all operations within the tree to that object.
These are really just ideas though, I don't see this happening unless
there's significant demand for it.

Evert

matt.s...@googlemail.com

unread,
Feb 12, 2009, 5:04:08 AM2/12/09
to SabreDAV Discussion

On Feb 11, 11:41 pm, Evert Pot <evert...@gmail.com> wrote:

> If your back-end allows it, it's definitely recommended to override  
> both copy and move. They will generally be quite slow.
>
> I personally have a mixed backend, which kinda looks like this :
>
> Project1
>    Templates - database backed
>      - template1 - database backed
>    Assets - filesystem backed

Yes, mine's a bit of a mixture along as well.

For that reason, something that would significantly speed things up
would be if there was the option to use file handles rather than
passing around the data and then using file_get_contents and
file_put_contents.

For the moment, uploading a 500Mb file involves (I think) uploading it
all into memory, passing it all to a function, then saving it all to
disk again.

Can I fix this with Sabre if I get a little deeper into it and start
looking at the Tree level? Or is it a fundamental limit of using PHP
to create a DAV server? That all the file data in the request must be
parsed into memory before it can be written to a file? A bit like
things used to be with file uploads?

Matt

Evert Pot

unread,
Feb 12, 2009, 9:45:42 AM2/12/09
to sabredav...@googlegroups.com
On 12-Feb-09, at 5:04 AM, matt.s...@googlemail.com wrote:
>
> Yes, mine's a bit of a mixture along as well.
>
> For that reason, something that would significantly speed things up
> would be if there was the option to use file handles rather than
> passing around the data and then using file_get_contents and
> file_put_contents.
>
> For the moment, uploading a 500Mb file involves (I think) uploading it
> all into memory, passing it all to a function, then saving it all to
> disk again.
>
> Can I fix this with Sabre if I get a little deeper into it and start
> looking at the Tree level? Or is it a fundamental limit of using PHP
> to create a DAV server? That all the file data in the request must be
> parsed into memory before it can be written to a file? A bit like
> things used to be with file uploads?
>

Right now php://temp streams are used where possible.. This means the
data will be stored on disk as soon as it surpasses 2MB.

I don't really know if this is the case for the request-body. I can
see PHP will want to place that entire string into memory.

Worth testing..

Evert

Reply all
Reply to author
Forward
0 new messages