Apache-Roaming

 view release on metacpan or  search on metacpan

lib/Apache/Roaming.pm  view on Meta::CPAN

    my $file = $self->{'file'};
    my $basedir = $self->{'basedir'};
    my $dir = $file;
    my $user = $self->{'user'};
    my $prevdir;

    while (($dir = File::Basename::dirname($dir))
	   and  (!$prevdir  or  ($dir ne $prevdir))) {
	if ($basedir eq $dir) {
	    my $userdir;
	    $userdir = File::Basename::basename($prevdir) if $prevdir;
	    if (!$prevdir  or  $userdir ne $user) {
		$self->{'status'} = Apache::Constants::FORBIDDEN();
		die "Access to $file not permitted for user $user";
	    }
	    return;
	}
	$prevdir = $dir;
    }
    $self->{'status'} = Apache::Constants::FORBIDDEN();
    die "Access to $file not permitted for user $user";
}


=pod

=head2 GET, PUT, MOVE, DELETE

  $ar_req->GET();
  $ar_req->PUT();
  $ar_req->MOVE();
  $ar_req->DELETE();

(Instance Methods) These methods are called finally for performing the
real action. With the exception of GET, they call I<Success> finally
for reporting Ok.

Alternative method names are possible, depending on the name of the
requested file. For example, if you request the file I<liprefs> via
GET, then it is checked whether your sublass has a method I<GET_liprefs>.
If so, this method is called rather than the default method I<GET>.
The alternative method names are obtained by removing all non-alpha-
numeric characters from the files base name. That is, if you request
a file I<pab.na2>, then the alternative name is I<pabna2>. Note, these
method names are case sensitive!

=cut

sub GET {
    my $self = shift;
    my $file = $self->{'file'};
    my $r = $self->{'request'};

    if (! -f $file) {
	$self->{'status'} = Apache::Constants::NOT_FOUND();
	die "No such file: $file";
    }
#    return Apache::DECLINED();
    my($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime) = stat _;
    my $fh = Symbol::gensym();
    if (!open($fh, "<$file")  ||  !binmode($fh)) {
  	die "Failed to open file $file: $!";
    }
    $r->set_last_modified($mtime);
    $r->content_type('text/plain');
    $r->no_cache(1);
    $r->header_out('content_length', $size);
    $r->send_http_header();
    if (!$r->header_only()) {
  	$r->send_fd($fh) or die $!;
    }
    return Apache::OK();
}


sub PUT {
    my $self = shift;
    my $file = $self->{'file'};
    my $r = $self->{'request'};

    $self->MkDir($file);

    my $fh = Symbol::gensym();

    open($fh, ">$file")
	or die "Failed to open $file: $!";
    binmode($fh)
	or die "Failed to request binmode for $file: $!";

    my $size = $r->header_in('Content-length');
    $r->hard_timeout("Apache->read");
    while ($size > 0) {
	my $buf = '';
	my $rdn = $r->read_client_block($buf, ($size < 1024) ? $size : 1024);
	if (!defined($rdn)) {
	    die "Error while reading $file from client: $!";
	}
	print $fh ($buf)
	    or die "Error while writing to client: $!";
	$size -= $rdn;
    }
    $r->kill_timeout();
    close($fh);
    $self->Success(201, 'URI created');
}


sub DELETE {
    my $self = shift;
    my $file = $self->{'file'};
    if (-f $file  and  !unlink $file) {
	$self->{'status'} = Apache::Constants::NOT_FOUND();
	die "Error while unlinking $file: $!";
    }
    $self->Success(201, 'URI deleted');
}


sub MOVE {
    my $self = shift;
    my $file = $self->{'file'};
    my $dir = File::Basename::dirname($file);
    my $r = $self->{'request'};
    my $uri = $r->uri();
    my $new_uri = $r->header_in('New-uri');

    unless ($new_uri) {
	$self->{'status'} = Apache::Constants::BAD_REQUEST();
	die "Missing header: New-uri";
    }
    if ($uri !~ /(.*)\//) {
	$self->{'status'} = Apache::Constants::BAD_REQUEST();
	die "URI $uri doesn't contain a '/'";
    }
    $uri = $1;
    if ($new_uri !~ /(.*)\/([^\/]+)/) {
	$self->{'status'} = Apache::Constants::BAD_REQUEST();
	die "New URI $new_uri doesn't contain a '/'";
    }
    $new_uri = $1;
    my $new_file = File::Spec->catfile($dir, $2);
    if ($uri ne $new_uri) {
	$self->{'status'} = Apache::Constants::FORBIDDEN();
	die "New URI $new_uri refers to another directory than $uri";
    }

    rename $file, $new_file
	or die "Error while renaming $file to $new_file: $!";



( run in 2.506 seconds using v1.01-cache-2.11-cpan-5837b0d9d2c )