
package Apache::ePerl;

require Apache;
require Apache::TieHandle;
use FileHandle;

sub handler {
    my($r) = @_;
    my $filename = $r->filename;

    local($|) = 1;
    %ENV = $r->cgi_env;

    if (-d $filename) {
      $r->log_reason("attempt to invoke directory as ePerl script");
      return 403;
    }

    $r->content_type("text/html");
    $r->send_http_header;

    my $exec_line = 0;
    local($/); undef $/;
    my $fh = new FileHandle $filename;
    my $data = <$fh>;
    $fh->close;

    my $index = index($data, "<\?");

    if ($index == -1) {  # no eperl in the file
      print($data);
      return 0;
    }


    while ($index != -1) {
      my $print_seg = substr($data, $start, $index);
      print($print_seg);

      $data   = substr($data, $index);
      $index  = index($data, "!>");

      my $cmd = substr($data, 0, $index+2);
      $cmd =~ s/<\?//;
      $cmd =~ s/!>//;
      eval($cmd);

      $data  = substr($data, $index+2);
      $index = index($data, "<\?");
    }
    print $data;

    return 0;
}
__END__

=head1 NAME

Apache::ePerl - Parse embedded perl code from HTML files on the fly

=head1 SYNOPSIS

 # add this to srm.conf
 PerlModule Apache::ePerl

 #in access.conf
 <Directory /WWW/htdocs/eperl>
 SetHandler perl-script
 PerlHandler Apache::ePerl::handler
 ...
 </Directory>

=head1 DESCRIPTION

Documents in the /WWW/htdocs/eperl directory will be parsed by the
Apache::ePerl handler, which will evaluate any embedded perl which has been
coded in the document before sending the response to the client.

=head2 Example:

<html>
<head>
<title>demo-01: CGI variable usage</title>
</head>
<body>
<h1>demo-01: CGI variable usage</h1>

Welcome user from <? print $ENV{'REMOTE_HOST'}; "; !>, nice to mee
t you!

</body>
</html>

=head2 Would return the following response to the client system:

<html>
<head>
<title>demo-01: CGI variable usage</title>
</head>
<body>
<h1>demo-01: CGI variable usage</h1>

Welcome user from 199.3.224.254, nice to meet you!

<UL></UL>

</body>
</html>


=head1 NOTES

This implementation of ePerl differs from the implementation by Ralf 
Engelschall in a few ways.  First, the ePerl interpreter will run
as an Apache module in this case, and should be faster than the 
external binary, since no fork()ing is necessary.  Secondly, all 
errors generated by ePerl code will be placed in the server's error
log, rather than sent to the browser.

Also note, that all comments about this implementation should be directed
to Mark Imbriaco <mark@itribe.net> and note Ralf Engelschall.

=head1 SEE ALSO

perl(1), Apache(3), http://www.engelschall.com/sw/eperl/

=head1 AUTHORS

Mark Imbriaco <mark@itribe.net>
ePerl Concept by Ralf Engelschall <rse@engelschall.com>
mod-perl by Doug MacEachern <dougm@osf.org>

