Send a link

Mason



After struggling a lot with mod_perl2 I finally found a configuration not too complicated and actually working.

IMPORTANT: Remember to make the libapreq2 with option WITH_MODPERL2=yes, to get Apache2::Request among other things :-)

The session management is unfortunately still in /tmp/ files - but I can live with that for a while. My last setup was on mod_perl1 and I had all sessions in MySQL which worked great (not to mention cleanup by date was dead easy).

Apache handler

Make a dir in apache's root called "Handlers". Inside, put a file called "Finger.pm" with content as:
package Handlers::Finger;

use strict;
use warnings;

use HTML::Mason::ApacheHandler;

my $comp_root = '/opt/www/sites';
my $data_dir = '/opt/www/mason';

my $ah = new HTML::Mason::ApacheHandler(
	comp_root => $comp_root,
	data_dir => $data_dir,
	allow_globals => [qw(%session)]
);

sub handler
{
    my ($r) = @_;
    return 404 if($r->filename =~ /autohandler$/); # never allow access to this directly!
    return 404 if($r->filename =~ /dhandler$/);    # same!
    return 404 if($r->filename =~ /\.mason$/);       # reserve this mask for components!

    my $status = $ah->handle_request($r);
    return $status;
}

1;


Virtual host configuration

Add the following as a vhost in your httpd.conf or whereever:
<VirtualHost *>
	ServerName test.finger.dk
	ServerAlias www.test.finger.dk
	DocumentRoot sites/test.finger.dk/htdocs
	ErrorLog sites/test.finger.dk/logs/error.log
	CustomLog sites/test.finger.dk/logs/access.log common

	DirectoryIndex index.mason index.html
	
	ErrorDocument 500 "500 - Fatal error, I made!"
	ErrorDocument 403 "403 - Access here, you have not!"
	ErrorDocument 404 "/error/"

	PerlModule HTML::Mason::ApacheHandler
	PerlModule CGI
	
	PerlModule Handlers::Finger
	
	#PerlSetVar MasonAllowGlobals %session

	<FilesMatch ".*\.mason$">
	#<FilesMatch ".*">
	#<LocationMatch "/.*">
	#<Directory sites/test.finger.dk/htdocs/>
		SetHandler perl-script
		#PerlHandler HTML::Mason::ApacheHandler
		PerlHandler Handlers::Finger
		PerlOptions +ParseHeaders
		Options +ExecCGI 
	#</LocationMatch>
	#</Directory>
	</FilesMatch>
	
	<Location />
		Order allow,deny
		Allow from all
	</Location>
</VirtualHost>


Session handling

Make a file called session.mason with this content:
<%once>

  use CGI::Cookie;
  use Apache::Session::File;

</%once>

<%init>

  my %cookie = fetch CGI::Cookie;
  #my %cookie = parse CGI::Cookie($r->headers_in('Cookie'));
  my $session_id = exists $cookie{finger_session} ? $cookie{finger_session}->value : undef;
  print "Cookie session = $session_id.<br>";
  
  #local *My::Session;
  #local *HTML::Mason::Commands::session;
  
  eval {
    tie %HTML::Mason::Commands::session, 'Apache::Session::File', $session_id, {
      Directory => '/tmp/sessions',
      LockDirectory => '/tmp/sessions',
    };
  };
   
  if ($@) {
    if ( $@ =~ m#^Object does not exist in the data store# ) {
      tie %session, 'Apache::Session::File', undef, {
        Directory => '/tmp/sessions',
        LockDirectory => '/tmp/sessions',
      };
      undef $cookie{finger_session};
    }
  }

  if(!$cookie{finger_session}) {
    my $cookie = CGI::Cookie->new(
      -name    =>  'finger_session',
      -value   =>  $session{_session_id},
      -expires =>  '+3M',
      -domain  =>  '.finger.dk',
      -path    =>  '/',
      -secure  =>  0
    );
    $cookie->bake($r);
    #$r->headers_out->set('Set-Cookie' => $cookie);
  }
  
  foreach(keys %session) {
    print "value of $_ = $session{$_}.<br>";
  }
  
  # Either or - both should not be needed - they do the same!?
  # http://search.cpan.org/~lds/CGI.pm-3.17/CGI/Cookie.pm
  #$new_c->bake($r);
  #$r->headers_out->set('Set-Cookie' => $new_c);
  
</%init>


File "autohandler"

In your file "autohandler" insert:
<%init>  
  print "Content-type: text/html\n\n";
  $m->comp("session.mason");
  print "<html><head><title>Whoa!</title></head><body>Auto Handler says hi.<br>";
</%init>

<%cleanup>
  print "<p>Auto Handler says bye.</body></html>";
  untie %session;
</%cleanup>