You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axkit-dev@xml.apache.org by na...@apache.org on 2004/07/13 20:05:46 UTC
cvs commit: xml-axkit/lib/Apache/AxKit/Provider File.pm
nachbaur 2004/07/13 11:05:46
Modified: . axconfig.c axconfig.h
lib/Apache/AxKit ConfigReader.pm
lib/Apache/AxKit/Provider File.pm
Added: lib/Apache/AxKit DirHandler.pm
lib/Apache/AxKit/DirHandler Basic.pm
Log:
Reviewed by: Kip Hampton
Added AxDirHandler directive to choose a custom directory handler for when AxHandleDirs is enabled
Revision Changes Path
1.19 +19 -2 xml-axkit/axconfig.c
Index: axconfig.c
===================================================================
RCS file: /home/cvs/xml-axkit/axconfig.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- axconfig.c 7 Jul 2003 22:29:50 -0000 1.18
+++ axconfig.c 13 Jul 2004 18:05:45 -0000 1.19
@@ -104,6 +104,7 @@
new->config_reader_module = 0;
new->contentprovider_module = 0;
new->styleprovider_module = 0;
+ new->dir_handler_module = 0;
new->default_style = 0;
new->default_media = 0;
new->cache_module = 0;
@@ -429,6 +430,13 @@
new->trace_intermediate = ap_pstrdup(p, parent_dir->trace_intermediate);
}
+ if (subdir->dir_handler_module) {
+ new->dir_handler_module = ap_pstrdup(p, subdir->dir_handler_module);
+ }
+ else if (parent_dir->dir_handler_module) {
+ new->dir_handler_module = ap_pstrdup(p, parent_dir->dir_handler_module);
+ }
+
new->debug_tidy =
subdir->debug_tidy != -1 ? subdir->debug_tidy :
parent_dir->debug_tidy;
@@ -1338,7 +1346,12 @@
{ "AxHandleDirs", ap_set_flag_slot,
(void *)XtOffsetOf(axkit_dir_config, handle_dirs),
OR_ALL, FLAG,
- "On or Off [default] to make AxKit process directory requests using XML::Directory" },
+ "On or Off [default] to make AxKit produce XML for directory requests" },
+
+ { "AxDirHandler", ax_set_module_slot,
+ (void *)XtOffsetOf(axkit_dir_config, dir_handler_module),
+ OR_ALL, TAKE1,
+ "alternative module to use for generating directory xml" },
{ "AxIgnoreStylePI", ap_set_flag_slot,
(void *)XtOffsetOf(axkit_dir_config, ignore_style_pi),
@@ -1459,6 +1472,10 @@
if (cfg->handle_dirs != -1) {
hv_store(retval, "HandleDirs",
10, (newSViv(cfg->handle_dirs)), 0);
+ }
+ if (cfg->dir_handler_module) {
+ hv_store(retval, "DirHandler",
+ 10, (newSVpv(cfg->dir_handler_module, 0)), 0);
}
if (cfg->dependency_checks != -1) {
1.9 +2 -1 xml-axkit/axconfig.h
Index: axconfig.h
===================================================================
RCS file: /home/cvs/xml-axkit/axconfig.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- axconfig.h 28 Jun 2002 01:26:01 -0000 1.8
+++ axconfig.h 13 Jul 2004 18:05:45 -0000 1.9
@@ -43,6 +43,7 @@
char * cache_module;
char * output_charset;
char * trace_intermediate;
+ char * dir_handler_module;
int debug_tidy;
int debug_level;
int translate_output;
1.19 +13 -1 xml-axkit/lib/Apache/AxKit/ConfigReader.pm
Index: ConfigReader.pm
===================================================================
RCS file: /home/cvs/xml-axkit/lib/Apache/AxKit/ConfigReader.pm,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- ConfigReader.pm 4 Aug 2003 23:05:17 -0000 1.18
+++ ConfigReader.pm 13 Jul 2004 18:05:45 -0000 1.19
@@ -193,6 +193,18 @@
0;
}
+sub DirHandlerClass {
+ my $self = shift;
+ if (my $alternate = $self->{cfg}{DirHandler} ||
+ $self->{apache}->dir_config('AxDirHandler')) {
+ AxKit::load_module($alternate);
+ return $alternate;
+ }
+
+ AxKit::load_module('Apache::AxKit::DirHandler::Basic');
+ return 'Apache::AxKit::DirHandler::Basic';
+}
+
sub IgnoreStylePI {
my $self = shift;
return $self->{cfg}{IgnoreStylePI} ||
1.1 xml-axkit/lib/Apache/AxKit/DirHandler.pm
Index: DirHandler.pm
===================================================================
# $Id: DirHandler.pm,v 1.1 2004/07/13 18:05:46 nachbaur Exp $
package Apache::AxKit::DirHandler;
use strict;
use Apache;
use Apache::Log;
use Apache::URI;
use AxKit;
use Data::Dumper;
use File::Basename;
sub new {
my $class = shift;
my $provider = shift;
my $self = bless {
provider => $provider,
directory => AxKit::FromUTF8($provider->{file}),
}, $class;
# init() ourselves, if a subclass wants to
$self->init(@_);
return $self;
}
sub init {
# blank - override to provide functionality
}
#
# return mtime information for all files in this directory
sub mtime {
my $self = shift;
my $dir = $self->{directory};
my $mtime = 0;
if (opendir(DIR, $dir)) {
while(my $line = readdir(DIR)) {
# stat the current file and, if it's mtime is bigger than
# anything we've so far seen, snag it
my @stat = stat(File::Spec->catfile($dir,$line));
$mtime = $stat[9] if ($stat[9] > $mtime);
}
AxKit::Debug(8, "Directory mtime is $mtime");
return $mtime;
}
AxKit::Debug(8, "Directory mtime calculations failed");
return undef;
}
#
# return the filename for the current request...its just plain easier
# to use this way IMHO.
sub _request_filename {
my $self = shift;
my $provider = $self->{provider};
my $apache = $provider->apache_request;
return $apache->filename;
}
#
# take a filename, and return a proper URI for that, given the
# current apache request
sub _request_uri {
my $self = shift;
my $path = shift;
my $provider = $self->{provider};
my $r = $provider->apache_request;
my $uri = Apache::URI->parse($r);
# Traverse through to the ".." directory
if ($path and $path eq '..') {
# We don't want to climb above the document_root
return undef if ($uri->path eq '/');
# trim off the last directory on the URI and return
# the modified Apache::URI object
my $new_path = $uri->path;
$new_path =~ s{/[^/]+/$} {/};
$uri->path($new_path);
}
# Process the "." directory
elsif ($path and $path eq '.' or basename($path) eq '.') {
# Take the path, which may be multi-leveled, and remove
# the "." directory from the end of it; if this is not
# multi-leveled, don't do anything.
$uri->path(dirname($uri->path . $path));
}
# For all other files, tack the filename onto the end of the URI
elsif ($path) {
$uri->path($uri->path . $path);
}
return ($uri, $uri->unparse) if (wantarray);
return $uri->unparse;
}
#
# pretty-format a filesize in kilobytes, megabytes, etc
sub _format_filesize {
my $self = shift;
my $size = shift;
my $factor = undef;
my $base = 1024;
my @suffix = qw( B kB MB GB TB PB );
for ($factor = $#suffix; $factor > 0; $factor--) {
last if ($size / $base ** $factor >= 1);
}
return sprintf('%.2f', $size / $base ** $factor) . $suffix[$factor];
}
1;
__END__
=head1 NAME
Apache::AxKit::DirHandler - base class for Directory handlers
=head1 SYNOPSIS
Override the base DirHandler class and enable it by using:
AxDirHandler MyClass
# alternatively use:
# PerlSetVar AxDirHandler MyClass
=head1 DESCRIPTION
AxKit supports the capability to handle directory requests. Therefore, instead of
relying on Apache to serve a Directory Index file or generating a file listing,
AxKit will generate XML representing the content of the indicated directory for
processing by your stylesheet pipeline.
In many cases the default XML grammar provided will be sufficient, but for those
instances when something more specific is necessary, this default behavior can be
overridden.
This class is a base-class implementing basic behavior, but must be inherited for
directory listings to function. To write your own directory handler, simply override
this class and implement the C<get_strref()> method.
=head1 PUBLIC METHODS
The following are the methods available from this class:
=head2 get_strref
This method is called to generate the XML contents of a directory. The "directory"
property of the object contains the path of the directory to be returned. The return
value is expected to be a reference to the XML string to be returned.
=head2 init()
This method is called shortly after object construction, and can be used to initialize
anything necessary to the operation of a directory handler.
=head2 mtime()
This returns the latest last modified time of any file or directory within the requested
directory. This is used for caching purposes.
=head1 PRIVATE METHODS
Apache::AxKit::DirHandler provides a few convenience methods that can make the business
of processing directory listings easier.
=head2 _request_filename
This returns the requested filename from the Apache object.
=head2 _request_uri
Given a filename relative to the currently processed directory, this will return a full
URI for the file. If called in a scalar context it will return the full URI, while in an
array context it will return both an Apache::URI object and the "unparsed" URI string.
=head2 _format_filesize
This will return a fancy filesize string (XkB, etc) for a given byte-size.
=cut
1.1 xml-axkit/lib/Apache/AxKit/DirHandler/Basic.pm
Index: Basic.pm
===================================================================
# $Id: Basic.pm,v 1.1 2004/07/13 18:05:46 nachbaur Exp $
package Apache::AxKit::DirHandler::Basic;
use strict;
use vars qw/@ISA/;
@ISA = ('Apache::AxKit::DirHandler');
use Apache;
use Apache::Log;
use AxKit;
use Apache::AxKit::DirHandler;
use File::Spec;
use Fcntl qw(O_RDONLY LOCK_SH);
sub get_strref {
my $self = shift;
local (*DIR);
my $dir = $self->{directory};
if (opendir(DIR, $dir)) {
my $output = '<?xml version="1.0" encoding="UTF-8"?>
<filelist xmlns="http://axkit.org/2002/filelist">
';
while(my $line = readdir(DIR)) {
my $xmlline = AxKit::ToUTF8($line);
$xmlline =~ s/&/&/;
$xmlline =~ s/</</;
my @stat = stat(File::Spec->catfile($dir,$line));
my $attr = "size=\"$stat[7]\" atime=\"$stat[8]\" mtime=\"$stat[9]\" ctime=\"$stat[10]\"";
$attr .= ' readable="1"' if (-r _);
$attr .= ' writable="1"' if (-w _);
$attr .= ' executable="1"' if (-x _);
if (-f _) {
$output .= "<file $attr>$xmlline</file>\n";
} elsif (-d _) {
$output .= "<directory $attr>$xmlline</directory>\n";
} else {
$output .= "<unknown $attr>$xmlline</unknown>\n";
}
}
$output .= "</filelist>\n";
return \$output;
}
return undef;
}
1;
__END__
=head1 NAME
Apache::AxKit::DirHandler::Basic - directory handler implementing a simple XML output
=head1 SYNOPSIS
Override the base DirHandler class and enable it by using:
AxHandleDirs on
AxDirHandler Apache::AxKit::DirHandler::Basic
# or
AxHandleDirs on
# This module is the default
=head1 DESCRIPTION
This module is the default Directory Handler when no handler is explicitly
specified. It is intended to be simple to use and easy to get started with.
=head1 SAMPLE OUTPUT
<?xml version="1.0" encoding="UTF-8"?>
<filelist xmlns="http://axkit.org/2002/filelist">
<directory size="4096" atime="1077320634" mtime="1077312841" ctime="1077312841" readable="1" executable="1">.</directory>
<directory size="4096" atime="1077316522" mtime="1076743711" ctime="1076743711" readable="1" executable="1">..</directory>
<file size="0" atime="1076770889" mtime="1076770889" ctime="1076770889" readable="1">index.xml</file>
<directory size="4096" atime="1076954718" mtime="1076774280" ctime="1076774280" readable="1" executable="1">images</directory>
<file size="0" atime="1077320634" mtime="1076770894" ctime="1076770894" readable="1">.htaccess</file>
<file size="580626" atime="1077319951" mtime="1076774007" ctime="1076774007" readable="1">link-4.1a.tar.gz</file>
<file size="708" atime="1077319951" mtime="1076774018" ctime="1076774018" readable="1" executable="1">Bender.pl</file>
</filelist>
=head1 SEE ALSO
L<Apache::AxKit::DirHandler>
=cut
1.17 +14 -30 xml-axkit/lib/Apache/AxKit/Provider/File.pm
Index: File.pm
===================================================================
RCS file: /home/cvs/xml-axkit/lib/Apache/AxKit/Provider/File.pm,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- File.pm 27 Apr 2004 16:57:14 -0000 1.16
+++ File.pm 13 Jul 2004 18:05:46 -0000 1.17
@@ -119,36 +119,14 @@
sub get_dir_xml {
my $self = shift;
- local (*DIR);
- my $dir = AxKit::FromUTF8($self->{file});
- if (opendir(DIR, $dir)) {
- my $output = '<?xml version="1.0" encoding="UTF-8"?>
-<filelist xmlns="http://axkit.org/2002/filelist">
-';
- while(my $line = readdir(DIR)) {
- my $xmlline = AxKit::ToUTF8($line);
- $xmlline =~ s/&/&/;
- $xmlline =~ s/</</;
- my @stat = stat(File::Spec->catfile($dir,$line));
- my $attr = "size=\"$stat[7]\" atime=\"$stat[8]\" mtime=\"$stat[9]\" ctime=\"$stat[10]\"";
- $attr .= ' readable="1"' if (-r _);
- $attr .= ' writable="1"' if (-w _);
- $attr .= ' executable="1"' if (-x _);
-
- if (-f _) {
- $output .= "<file $attr>$xmlline</file>\n";
- } elsif (-d _) {
- $output .= "<directory $attr>$xmlline</directory>\n";
- } else {
- $output .= "<unknown $attr>$xmlline</unknown>\n";
- }
- }
- $output .= "</filelist>\n";
- AxKit::Debug(8,"Generated file list: $output");
+ my $r = AxKit::Apache->request;
+ my $package = $AxKit::Cfg->DirHandlerClass();
+ my $dirhandler = $self->{dirhandler_obj}
+ || ($self->{dirhandler_obj} = $package->new($self));
+ my $output = $dirhandler->get_strref();
+ AxKit::Debug(8,"Generated file list: $$output") if (defined($$output));
return $output;
}
- return undef;
-}
sub decline {
my $self = shift;
@@ -207,6 +185,12 @@
sub mtime {
my $self = shift;
+ if ($self->_is_dir and $AxKit::Cfg->HandleDirs()) {
+ my $package = $AxKit::Cfg->DirHandlerClass();
+ my $dirhandler = $self->{dirhandler_obj}
+ || ($self->{dirhandler_obj} = $package->new($self));
+ return $dirhandler->mtime();
+ }
return $self->{mtime} if defined $self->{mtime};
return ($self->{mtime} = (stat(AxKit::FromUTF8($self->{file})))[9]);
}
@@ -233,7 +217,7 @@
my $self = shift;
if ($self->_is_dir()) {
my $xml = $self->{dir_xml} || $self->get_dir_xml();
- return \$xml if $xml;
+ return $xml if $$xml;
throw Apache::AxKit::Exception::IO(
-text => "directory $self->{file} cannot be read");
}