insaniac has asked for the wisdom of the Perl Monks concerning the following question:

hi all,

At the moment I'm reading "Practical mod_perl", and usually I want to try out the examples. Like the example starting on page 298 (the BrowseSee.pm). I've checked the errata et al, I couldn't find anything about the example, so I guess it's not been fixed yet (or I'm just mis-using it).

Of course it doesn't work like expected :-)

Lemme startof with the code I have (I have tweaked the example a little bit)
package Apache::BrowseSee; use strict; use Apache::Constants qw(:common); use File::Spec::Functions qw(catdir canonpath curdir updir); use File::Basename 'dirname'; my $document_root = '/home/insaniac/work/code/perl/www'; sub new {bless {}, shift} sub handler ($$) { my ($self,$r)= @_; $self = $self->new unless ref $self; $self->{r} = $r; $self->{r}->document_root($document_root); $self->{dir}= $r->path_info || '/'; $self->{uri}= $r->uri || '/'; $self->{dirs} = {}; $self->{files} = {}; eval { $self->fetch }; return NOT_FOUND if $@; $self->head; print "current dir:",$self->{dir},"<br />"; print "path info:",$r->path_info,"<br />"; print "uri:",$r->uri,"<br />"; $self->render; $self->tail; return OK; } sub fetch { my $self = shift; my $doc_root = Apache->document_root; my $base_dir = canonpath(catdir($doc_root,$self->{dir})); my $base_entry = $self->{dir} eq '/' ? '' : $self->{dir}; my $dh = Apache::gensym(); opendir $dh, $base_dir or die "Cannot open $base_dir: $!"; for (readdir $dh) { next if $_ eq curdir(); my $full_dir = catdir $base_dir, $_; my $entry = "$base_dir/$_"; if ( -d $full_dir ) { if ( $_ eq updir() ){ $entry = dirname $self->{dir}; next if catdir($base_dir,$entry) eq $doc_root; } $self->{dirs}{$_} = $entry; } else { $self->{files}{$_} = $entry; } } closedir($dh); } sub head { my $self = shift; $self->{r}->send_http_header("text/html"); print "<html><head><title>Dir: $self->{dir}</title></head><body>"; print "<h1>Browse And See</h1>"; } sub tail { my $self = shift; print "</body></html>"; } sub render { my $self = shift; my $location = $self->{r}->location; print "<h2>Current directory: ${location}$self->{dir}</h2>"; print "<p>location:$location</p>"; print qq{<a href="${location}$self->{dir}$_">$_</a><br />} for sort keys %{$self->{dirs} || {} }; print qq{$_<br />} for sort keys %{ $self->{files} || {} }; } 1;
And my Apache config:
Alias /browse /home/insaniac/work/code/perl/ <Location /browse> SetHandler perl-script PerlHandler Apache::BrowseSee </Location>
Now, all works well, until you click on of a links (the subdirectories)... it doesn't work. Lemme clarify:

The dir I'm scanning looks like this:

insaniac][amano: ~/work/code/perl/www : ls -F Apache/ Bonsai/ sessions/
If you click on one these subdirs in the HTML page rendered by modperl, nothing happens. BUT, the request_uri seems to have catched the subdir, because the first lines of my HTML page show:
Browse And See current dir:/ path info: uri:/browse/Bonsai
So, the path_info() method returns undef, but the request contains the subdir! If I add the name of the dir to the uri (for instance /browse/Bonsai/Bonsai ), all works perfect! This I don't understand

So, my deepest apologies for this lengthy post, but this was the only way to explain (at least for me..)

Thanks in advance for helping me! (and maybe some others who are stuck with this example)

to ask a question is a moment of shame
to remain ignorant is a lifelong shame

Replies are listed 'Best First'.
Re: [mod_perl] path_info() problem
by merlyn (Sage) on May 10, 2005 at 10:06 UTC
    Alias /browse /home/insaniac/work/code/perl/
    I'm not awake enough to parse through the rest of your problem, but let me start by saying two things.

    First, an "Alias" like that one is begging for trouble. You need to have both the left and right sides of an Alias either with a slash, or without. And if you put both (which is sometimes necessary), put the pair with a slash first. Keep in mind that Alias does a literal substitition.

    Second, content handlers must be very careful about how they handle being passed a directory name. If you are handed a URL that maps to a directory name, but that URL does not end in a slash, you must return DECLINED, which will cause the core directory module to issue an external redirect to the user. The updated URL from the browser will synchronize the browser's view of the directory (now ending in a slash) with your view of the directory.

    I have an example of this (including this description) in my mod_perl picture handler. Specifically, examine the code for line 95, and how you would end up there (especially the DIR_MAGIC_TYPE earlier).

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

      thanks merlyn, removing the Alias made the code work! (and of course: the Alias line is NOT in the book, so it was my own stupid fault)

      to ask a question is a moment of shame
      to remain ignorant is a lifelong shame

Re: [mod_perl] path_info() problem
by davis (Vicar) on May 10, 2005 at 10:07 UTC
    Said in the CB, but you scarpered for foodage :) :
    Remove the Alias line from your Apache config file, as path_info returns the path after Apache's parsed it.

    davis
    Kids, you tried your hardest, and you failed miserably. The lesson is: Never try.
      thanks dude ;-)

      to ask a question is a moment of shame
      to remain ignorant is a lifelong shame