You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by David Arnold <da...@northcoast.com> on 2004/06/15 05:12:51 UTC
A CGI.pm script
All,
Running:
[root@scinux cgi-perl]# /usr/sbin/apachectl -v
Server version: Apache/2.0.40
Server built: Nov 27 2003 11:04:06
MOD_PERL=mod_perl/1.99_07-dev
I've added these changes to httpd.conf:
ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
<Directory "/var/www/cgi-bin">
AllowOverride None
Options None
Order allow,deny
Allow from all
</Directory>
Alias /cgi-perl/ "/var/www/cgi-perl/"
<Location /cgi-perl>
SetHandler perl-script
PerlResponseHandler ModPerl::Registry
PerlOptions +ParseHeaders
Options ExecCGI
</Location>
LoadModule perl_module modules/mod_perl.so
PerlModule Apache2
PerlModule Apache::compat
The script at the end of this post is a script from Lincoln Stein's CGI.pm.
It runs fine when accessed with http://hostname/cgi-bin/graffiti.pl.
However, when accessed with http://hostname/cgi-perl/graffiti.pl, I get:
Server error!
The server encountered an internal error and was unable to complete your
request.
Error message:
Failed opening session state file ./STATES/259344: No such file or
directory at /var/www/cgi-perl/graffiti.pl line 104.
If you think this is a server error, please contact the webmaster
Error 500
The script does try to write a new file in real time. The permissions for
the location are identical.
For cgi-bin:
drwxr-xr-x 2 apache apache 1024 Jun 14 20:03 STATES
For cgi-perl:
drwxr-xr-x 2 apache apache 1024 Jun 14 18:39 STATES
I've pretty much narrowed the error down when the script
/cgi-perl/graffiti.pl attempts to open a nonexistent file for writing in
the STATES folder through the subroutine save_state at the very bottom of
the script.
My question: Do I need to set some configuration to allow Apache and/or
mod-perl to create or write to files in cgi-perl/STATES/? If so, how do I
do this?
****************************************************************************
*********************
The file graffiti.pl
**********snip**************snip***************snip**************snip*******
*********************
#! /usr/bin/perl -w
# graffiti.pl
# constants
$STATE_DIR = "./STATES";
use CGI::Apache qw(:standard);
$session_key = path_info();
$session_key =~ s|^/||;
unless ( valid($session_key) ) {
$session_key = generate_session_key();
print redirect( url() . "/$session_key" );
exit 0;
}
# Pull out our current CGI state variables to prevent them from being
# overwritten when we restore our previous state.
@new_items = param('item');
$action = param('action');
fetch_old_state($session_key);
# Add new items to the old list of items
if ( $action eq 'ADD' ) {
@old_items = param('item');
param( 'item', @old_items, @new_items );
}
elsif ( $action eq 'CLEAR' ) {
Delete('item');
}
# Save the new list to disk
save_state($session_key);
# Now, at last, generate something for the user to look at
print header,
start_html("The growing list"),
<<END;
<h1>The Growing List</h1>
Type a short phrase into the text fields below. Press <i>ADD</i> to
append it to the history of the phrases that you've typed. The
list is maintained on disk at the server end, so it won't get out of
order if you press the "back" button. Press <i>CLEAR</i> to clear
the list and start fresh. Bookmark this page to come back to the
list later.
END
print start_form,
textfield(-name=>'item', -default=>'', -size=>'50', -override=>1),
p(),
submit(-name=>'action', -value=>'CLEAR'),
submit(-name=>'action', -value=>'ADD'),
end_form,
hr,
h2('Current List');
if (param('item'))
{
my @items=param('item');
print ol(li(\@items));
} else {
print em('Empty');
}
print <<END;
<hr>
<a href="/">Home Page</a></address>
END
print end_html;
# subroutine generate_session_key
sub generate_session_key {
my $key;
do {
$key = int( rand(1000000) );
} until ( ! -e "STATE_DIR/$key" );
return $key;
} # end subroutine generate_session_key
# subroutine valid
sub valid {
my $key = shift;
return $key =~ /^\d+$/;
}
# Open the existing file, if any, and read the current state from
# it. We use the CGI object here, because it's straightforward to do
# so. We don't check for success or the open() call, becuse if there
# is no file yet, the new CGI(FILHANDLE) call will return an empty
# parameter list, which is exactly what we want.
sub fetch_old_state {
my $session_key = shift;
open( SAVEDSTATE, "$STATE_DIR/$session_key" ) || return;
restore_parameters(SAVEDSTATE);
close SAVEDSTATE;
}
sub save_state {
my ($session_key) = @_;
open( SAVEDSTATE, ">$STATE_DIR/$session_key" )
|| die "Failed opening session state file $STATE_DIR/$session_key: $!";
save_parameters(SAVEDSTATE);
close SAVEDSTATE;
}
--
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html
Re: A CGI.pm script
Posted by David Arnold <da...@northcoast.com>.
Larry,
That was it. By setting STATE_DIR to the absolute path, the script now runs.
Can folks on this list perhaps share a little discussion about methods I
could use to "chdir to the right directory at script startup." It would
help to see a sampling of idea.
Thanks. :-)
At 11:57 PM 6/14/04 -0400, you wrote:
>Hi David -
>
>> MOD_PERL=mod_perl/1.99_07-dev
> [cut]
>> It runs fine when accessed with http://hostname/cgi-bin/graffiti.pl.
>> However, when accessed with http://hostname/cgi-perl/graffiti.pl, I get:
>>
>> Server error!
>> The server encountered an internal error and was unable to complete your
>> request.
>> Error message:
>> Failed opening session state file ./STATES/259344: No such file or
>> directory at /var/www/cgi-perl/graffiti.pl line 104.
>
>That's a really old version of mod_perl 2. I think for that version,
>ModPerl::Registry did not chdir to the script directory before running the
>script (because of some thread-related problems). If you print the
>current directory from inside your script somewhere e.g.:
>
> print "<p>current directory is: ", `pwd`, "</p>";
>
>you'll probably find you're not in the directory you thought you were.
>
>You need to either chdir to the right directory at script startup, or
>define $STATE_DIR using an absolute path instead of a relative path.
>
>
>HTH,
>Larry
>
>
>
>
>
--
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html
Re: A CGI.pm script
Posted by Stas Bekman <st...@stason.org>.
Larry Leszczynski wrote:
> Hi David -
>
>
>>MOD_PERL=mod_perl/1.99_07-dev
>
> [cut]
>
>>It runs fine when accessed with http://hostname/cgi-bin/graffiti.pl.
>>However, when accessed with http://hostname/cgi-perl/graffiti.pl, I get:
>>
>>Server error!
>>The server encountered an internal error and was unable to complete your
>>request.
>>Error message:
>>Failed opening session state file ./STATES/259344: No such file or
>>directory at /var/www/cgi-perl/graffiti.pl line 104.
>
>
> That's a really old version of mod_perl 2. I think for that version,
> ModPerl::Registry did not chdir to the script directory before running the
> script (because of some thread-related problems).
And it still doesn't do that. It can't do that, since under threads it'll
wreak havoc - as chdir affects all threads:
http://perl.apache.org/docs/2.0/user/porting/compat.html#C_Apache__Registry___C_Apache__PerlRun__and_Friends
http://perl.apache.org/docs/2.0/user/coding/coding.html#Thread_environment_Issues
http://perl.apache.org/docs/2.0/user/porting/compat.html#C__r_E_gt_chdir_file_
The most recent version of FindBin should work for mod_perl. So instead of
requiring a file relatively use FindBin to find where the script's dir is.
--
__________________________________________________________________
Stas Bekman JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org http://ticketmaster.com
--
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html
Re: A CGI.pm script
Posted by Larry Leszczynski <la...@emailplus.org>.
Hi David -
> MOD_PERL=mod_perl/1.99_07-dev
[cut]
> It runs fine when accessed with http://hostname/cgi-bin/graffiti.pl.
> However, when accessed with http://hostname/cgi-perl/graffiti.pl, I get:
>
> Server error!
> The server encountered an internal error and was unable to complete your
> request.
> Error message:
> Failed opening session state file ./STATES/259344: No such file or
> directory at /var/www/cgi-perl/graffiti.pl line 104.
That's a really old version of mod_perl 2. I think for that version,
ModPerl::Registry did not chdir to the script directory before running the
script (because of some thread-related problems). If you print the
current directory from inside your script somewhere e.g.:
print "<p>current directory is: ", `pwd`, "</p>";
you'll probably find you're not in the directory you thought you were.
You need to either chdir to the right directory at script startup, or
define $STATE_DIR using an absolute path instead of a relative path.
HTH,
Larry
--
Report problems: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
List etiquette: http://perl.apache.org/maillist/email-etiquette.html