Apache-Roaming

 view release on metacpan or  search on metacpan

MANIFEST  view on Meta::CPAN

ChangeLog			Revision history
MANIFEST			This file
MANIFEST.SKIP
Makefile.PL			Makefile generator
README				I mean it! :-)
lib/Apache/Roaming.pm		The roaming access module
lib/Apache/Roaming/LiPrefs.pm	A module for parsing liprefs files
lib/Bundle/Apache/Roaming.pm	A bundle for CPAN installation
t/01base.t			Base test (Loading the module)
t/10methods.t			Testing the PUT, GET, MOVE and DELETE methods
t/20liprefs.t			Testing Apache::Roaming::LiPrefs

README  view on Meta::CPAN

        http://www.esat.kuleuven.ac.be/~vermeule/roam/put

    Compared to Apache::Roaming, this script doesn't need mod_perl. On the
    other hand it doesn't support the MOVE method, thus you need to set the
    li.prefs.http.useSimplePut attribute in your Netscape preferences. Due
    to the missing MOVE method, it may be even slower than Apache::Roaming
    and perhaps a little bit less stable.

    The modules features are:

    *       GET, HEAD, PUT, DELETE and MOVE are handled by the module. In
            particular the Non-standard MOVE method is implemented, although
            Apache doesn't know it by default. Thus you need no set the
            li.prefs.http.useSimplePut attribute to true.

    *       Directories are created automatically.

    *       The module is subclassable, so that you can create profiles on
            the fly or parse and modify the user preferences. See the
            Apache::Roaming::LiPrefs(3) manpage for an example subclass.

README  view on Meta::CPAN

    well use it by itself, but IMO the most important possibility is
    overwriting the GET method for complete control over the users settings.

  handler

      $result = Apache::Roaming->handler($r);

    (Class Method) The *handler* method is called by the Apache server for
    any request. It receives an Apache request $r. The methods main task is
    creating an instance of Apache::Roaming by calling the *new* method and
    then passing control to the *Authenticate*, *CheckDir* and *GET*, *PUT*,
    *DELETE* or *MOVE*, respectively, methods.

  handler_type

      $status = Apache::Roaming->handler_type($r)

    (Class Method) This method is required only, because the Apache server
    would refuse other methods than GET otherwise. It checks whether the
    requested method is GET, PUT, HEAD, DELETE or MOVE, in which case it
    returns the value OK. Otherwise the value DECLINED is returned.

  new

      $ar_req = Apache::Roaming->new(%attr);

    (Class Method) This is the modules constructor, called by the *handler*
    method. Instances of Apache::Request have the following attributes:

    basedir The roaming servers base directory, as an absolute path. You set
            this using a PerlSetVar instruction, see the INSTALLATION
            manpage above for an example.

    file    This is the path of the file being created (PUT), read (GET),
            deleted (DELETE) or moved (MOVE). It's an absolute path.

    method  The requested method, one of HEAD, GET, PUT, MOVE or DELETE.

    request This is the Apache request object.

    status  If a method dies, it should set this value to a return code like
            SERVER_ERROR (default), FORBIDDEN, METHOD_NOT_ALLOWED, or
            something similar from Apache::Constants. See the
            Apache::Constants(3) manpage. The *handler* method will catch
            Perl exceptions for you and generate an error page.

    user    Name the user authenticated as.

README  view on Meta::CPAN

  CheckDir

      $ar_req->CheckDir();

    (Instance method) Once the user is authenticated, this method should
    determine whether the user is permitted to access the requested URI. The
    current implementation verifies whether the user is accessing a file in
    the directory $basedir/$user. If not, a Perl exception is thrown with
    $ar_req->{'status'} set to FORBIDDEN.

  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 *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 *liprefs* via GET,
    then it is checked whether your sublass has a method *GET_liprefs*. If
    so, this method is called rather than the default method *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
    *pab.na2*, then the alternative name is *pabna2*. Note, these method
    names are case sensitive!

  MkDir

      $ar_req->MkDir($file);

    (Instance Method) Helper function of *PUT*, creates the directory where
    $file is located, if it doesn't yet exist. Works recursively, if more
    than one directory must be created.

  Success

      $ar_req->Success($status, $text);

    (Instance Method) Creates an HTML document with status $status,
    containing $text as success messages.

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

preferences. Due to the missing MOVE method, it may be even slower
than Apache::Roaming and perhaps a little bit less stable.


The modules features are:

=over 8

=item *

GET, HEAD, PUT, DELETE and MOVE are handled by the module. In particular
the Non-standard MOVE method is implemented, although Apache doesn't know
it by default. Thus you need no set the li.prefs.http.useSimplePut
attribute to true.

=item *

Directories are created automatically.

=item *

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



=head2 handler

  $result = Apache::Roaming->handler($r);

(Class Method) The I<handler> method is called by the Apache server
for any request. It receives an Apache request B<$r>. The methods
main task is creating an instance of Apache::Roaming by calling the
I<new> method and then passing control to the I<Authenticate>,
I<CheckDir> and I<GET>, I<PUT>, I<DELETE> or I<MOVE>, respectively,
methods.

=cut

sub handler ($$) {
    my($class, $r) = @_;

    my $file = File::Spec->canonpath(URI::Escape::uri_unescape($r->filename()));

    if ($file=~/IMAP$/) {

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

		    'request' => $r)
    };
    if ($@) {
	$r->log_reason($@, $file);
	return Apache::Constants::SERVER_ERROR();
    }

    eval {
	$self->Authenticate();
	$self->CheckDir();
	if ($self->{'method'} !~ /(?:GET|PUT|DELETE|MOVE)/) {
	    $self->{'status'} = Apache::Constants::HTTP_METHOD_NOT_ALLOWED();
	    die "Unknown method: $self->{'method'}";
	}

	my $method = $self->{'method'};
	my $f = File::Basename::basename($file);
	$f =~ s/\W//g;
	my $m = "$method\_$f";
	UNIVERSAL::can($self, $m) ? $self->$m() : $self->$method();
    };

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



=pod

=head2 handler_type

  $status = Apache::Roaming->handler_type($r)

(Class Method) This method is required only, because the Apache server
would refuse other methods than GET otherwise. It checks whether the
requested method is GET, PUT, HEAD, DELETE or MOVE, in which case it
returns the value OK. Otherwise the value DECLINED is returned.

=cut


sub handler_type ($$) {
    my($class, $r) = @_;

    if ($r->method() =~ /(?:GET|PUT|DELETE|MOVE)/) {
	$r->handler('perl-script');
	return Apache::Constants::OK();
    }
    return Apache::Constants::DECLINED();
}


=pod

=head2 new

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

=over 8

=item basedir

The roaming servers base directory, as an absolute path. You set this
using a PerlSetVar instruction, see L<INSTALLATION> above for an
example.

=item file

This is the path of the file being created (PUT), read (GET), deleted
(DELETE) or moved (MOVE). It's an absolute path.

=item method

The requested method, one of HEAD, GET, PUT, MOVE or DELETE.

=item request

This is the Apache request object.

=item status

If a method dies, it should set this value to a return code like
SERVER_ERROR (default), FORBIDDEN, METHOD_NOT_ALLOWED, or something
similar from Apache::Constants. See L<Apache::Constants(3)>.

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

	}
	$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>.

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

    $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: $!";

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

    $self->Success(201, 'URI moved');
}


=pod

=head2 MkDir

  $ar_req->MkDir($file);

(Instance Method) Helper function of I<PUT>, creates the directory
where $file is located, if it doesn't yet exist. Works recursively,
if more than one directory must be created.

=cut

sub MkDir {
    my $self = shift;  my $file = shift;
    my $dir = File::Basename::dirname($file);
    return if -d $dir;
    $self->MkDir($dir);

t/10methods.t  view on Meta::CPAN

alarm 120;

print "Creating a user agent.\n";
my $ua = LWP::UserAgent->new();
Test($ua);

sleep 5;
my $contents = 'abcdef';
my $testfile = File::Spec->catdir($cfg->{'roaming_dir'}, "foo bar", "test");
unlink $testfile;
Request($ua, 'PUT', '/roaming/foo bar/test', 'text/plain', $contents);
TestContents($testfile, $contents);

my $block = '';
for (my $i = 0;  $i < 256;  $i++) {
    $block .= chr($i);
}
my $contents2 = $block x 40;
my $testfile2 = File::Spec->catdir($cfg->{'roaming_dir'}, "foo bar", "test2");
unlink $testfile2;
Request($ua, 'PUT', '/roaming/foo bar/test2', 'text/plain', $contents2);
TestContents($testfile2, $contents2);

my $res = Request($ua, 'GET', '/roaming/foo bar/test');
Test($res->content()  and  ($res->content() eq $contents));
$res = Request($ua, 'GET', '/roaming/foo bar/test2');
Test($res->content()  and  ($res->content() eq $contents2));


my $testfile3 = File::Spec->catdir($cfg->{'roaming_dir'}, "foo bar", "test3");
unlink $testfile3;

t/20liprefs.t  view on Meta::CPAN

alarm 120;

print "Creating a user agent.\n";
my $ua = LWP::UserAgent->new();
Test($ua);

sleep 5;
my $contents = 'abcdef';
my $testfile = File::Spec->catdir($cfg->{'roaming_dir'}, "foo bar", "test");
unlink $testfile;
Request($ua, 'PUT', '/roaming/foo bar/test', 'text/plain', $contents);
TestContents($testfile, $contents);

my $block = '';
for (my $i = 0;  $i < 256;  $i++) {
    $block .= chr($i);
}
my $contents2 = $block x 40;
my $testfile2 = File::Spec->catdir($cfg->{'roaming_dir'}, "foo bar", "test2");
unlink $testfile2;
Request($ua, 'PUT', '/roaming/foo bar/test2', 'text/plain', $contents2);
TestContents($testfile2, $contents2);

my $res = Request($ua, 'GET', '/roaming/foo bar/test');
Test($res->content()  and  ($res->content() eq $contents));
$res = Request($ua, 'GET', '/roaming/foo bar/test2');
Test($res->content()  and  ($res->content() eq $contents2));


my $testfile3 = File::Spec->catdir($cfg->{'roaming_dir'}, "foo bar", "test3");
unlink $testfile3;



( run in 0.344 second using v1.01-cache-2.11-cpan-4e96b696675 )