Apache-WebDAV
view release on metacpan or search on metacpan
lib/Apache/WebDAV.pm view on Meta::CPAN
#proppatch => 1,
#post => 1,
#trace => 1,
#lock => 1,
#unlock => 1,
);
#
# Constructor. Does nothing.
#
sub new
{
my $class = shift;
bless {}, $class;
}
#
# Specify which modules will handle which paths.
#
sub register_handlers
{
my ($self, @handlers) = @_;
$self->{'handlers'} = \@handlers;
}
#
# Process the request. The $r is the apache object passed in from the mod_perl
# handler.
#
sub process
{
my ($self, $r) = @_;
my $uri = $r->uri();
my $method = lc($r->method());
my $handler = $self->get_handler_for_path($uri);
if($implemented{$method})
{
return $self->$method($r, $handler);
}
else
{
return DECLINED;
}
}
#
# Started working on this, targetted clients don't need it, never finished.
#
# sub proppatch
# {
# my ($self, $r, $handler) = @_;
#
# $r->status(200);
# $r->header_out("Allow",
# "OPTIONS, HEAD, GET, PUT, " .
# "DELETE, MKCOL, PROPPATCH, PROPFIND, COPY, MOVE");
# $r->header_out("DAV", "1,<http://apache.org/dav/propset/fs/1>");
# $r->send_http_header();
#
# return OK;
# }
#
# Copy a resource to another location.
#
sub copy
{
my ($self, $r, $handler) = @_;
my $path = $r->uri();
my $destination = $r->header_in('Destination');
my $depth = $r->header_in('Depth');
my $overwrite = $r->header_in('Overwrite');
# Default according to the book is overwrite = T
if(!defined($overwrite))
{
$overwrite = 'T';
}
# Translate the destination into a usable format
$destination = URI->new($destination)->path();
# If it's a regular file, don't sweat it
if($handler->test('f', $path))
{
return $self->copy_file($r, $handler, $path, $destination, $overwrite);
}
# Otherwise, we're copying a directory and we have to do it recursively.
# The logic for this was taken from Net::DAV::Server. It's creepy.
# We can't really go to infinity, but we can fake it.
$depth = 100 if defined($depth) && $depth eq 'infinity';
# Search for source files that we have to copy
my @files = map { s|/+|/|g; $_ }
File::Find::Rule::Filesys::Virtual->virtual($handler)->file->maxdepth($depth)->in($path);
# Search for source directories that we have to copy (didn't I tell you it
# was creepy?)
my @dirs = reverse sort
grep { $_ !~ m|/\.\.?$| }
map { s|/+|/|g; $_ }
File::Find::Rule::Filesys::Virtual->virtual($handler)->directory->maxdepth($depth)->in($path);
push @dirs, $path;
# Create all required directories first
foreach my $dir (sort @dirs)
{
my $dest_dir = $dir;
$dest_dir =~ s/^$path/$destination/;
lib/Apache/WebDAV.pm view on Meta::CPAN
# Based on the requested path ($uri), figure out which module will
# handle the request. The modules must be subclasses of
# Filesys::Virtual.
my $module;
my $path_handled;
my %args;
foreach my $mod (@{$self->{'handlers'}})
{
my $path = $mod->{'path'};
if($uri =~ /^$path/)
{
$module = $mod->{'module'};
$path_handled = $path;
%args = %{$mod->{'args'}} if defined($mod->{'args'});
}
}
my $handler = $module->new({
root_path => $path_handled,
cwd => $uri,
%args
});
return $handler;
}
1;
__END__
=head1 NAME
Apache::WebDAV - Extensible WebDAV server for Apache.
=head1 SYNOPSIS
use Apache::WebDAV;
=head1 ABSTRACT
Write perl modules to handle file transfers through WebDAV.
=head1 DESCRIPTION
Apache::WebDAV is a WebDAV server implementation. It was originally based on Net::DAV::Server (which isn't compatible with Apache), but has undergone significant architectural changes. Apache::WebDAV can be used with a simple mod_perl handler and t...
It is also possible to use different Filesys::Virtual subclasses to respond to different paths under your WebDAV root. This allows you to have some sections interact with the filesystem, others with a database, etc.
=head1 WebDAV Standards Compatibility
The WebDAV protocol is unclear and client behavior differs drastically. During development of this module, the following clients were identified as targets for support:
WebDrive (windows)
Transmit (osx)
Goliath (osx)
Cadaver (linux)
Konqueror (linux)
HTTP::DAV (perl)
The MacOSX Finder is also supported, assuming your Filesys::Virtual subclass is fully and correctly implemented. Specifically, you can't expect the Finder to "PUT" a file in one nice step, rather, it takes multiple requests and it's difficult to pro...
In addition, depending on your Filesys::Virtual subclass, of course, this module passes most of the WebDAV Litmus tests (http://www.webdav.org/neon/litmus/) without errors or warnings. Specifically:
OPTIONS for DAV: header
PUT, GET with byte comparison
MKCOL
DELETE (collections, non-collections)
COPY, MOVE using combinations of:
overwrite t/f
destination exists/doesn't exist
collection/non-collection
However, there is currently no support for LOCKING or PROPERTY MANIPULATION.
Finally, there are certain pieces of code in this module that purposefully break from the WebdAV protocol in order to support a specific client. As of this writing, both Goliath and WebDrive require these hacks. (Both are commented in the code.)
Microsoft Internet Explorer "Web Folders" do not seem to work and no effort has been made to figure out why.
Here is the output of the Litmus Test when running basic, copymove, and http:
$ echo $TESTS
basic copymove http
lozier@ruggles:~$ litmus http://pg.ruggles:8080/ApacheDAV
-> running `basic':
0. init.................. pass
1. begin................. pass
2. options............... pass
3. put_get............... pass
4. put_get_utf8_segment.. pass
5. mkcol_over_plain...... pass
6. delete................ pass
7. delete_null........... pass
8. delete_fragment....... WARNING: DELETE removed collection resource with Request-URI including fragment; unsafe
...................... pass (with 1 warning)
9. mkcol................. pass
10. mkcol_again........... pass
11. delete_coll........... pass
12. mkcol_no_parent....... pass
13. mkcol_with_body....... pass
14. finish................ pass
<- summary for `basic': of 15 tests run: 15 passed, 0 failed. 100.0%
-> 1 warning was issued.
-> running `copymove':
0. init.................. pass
1. begin................. pass
2. copy_init............. pass
3. copy_simple........... pass
4. copy_overwrite........ pass
5. copy_nodestcoll....... pass
6. copy_cleanup.......... pass
7. copy_coll............. pass
8. move.................. pass
9. move_coll............. pass
10. move_cleanup.......... pass
11. finish................ pass
<- summary for `copymove': of 12 tests run: 12 passed, 0 failed. 100.0%
-> running `http':
0. init.................. pass
1. begin................. pass
2. expect100............. pass
3. finish................ pass
<- summary for `http': of 4 tests run: 4 passed, 0 failed. 100.0%
The props tests mostly fail.
( run in 0.484 second using v1.01-cache-2.11-cpan-13bb782fe5a )