blob: 28f4f49f81dd8e9f1545839f693997eca7a8705a [file] [log] [blame]
package Apache::httpd_conf;
use strict;
use vars qw($VERSION $AUTOLOAD);
use File::Path ();
use IO::File ();
use Cwd ();
$VERSION = '0.01';
sub new {
my $class = shift;
my $self = bless {
base => "",
@_,
}, $class;
$self->{base} ||= (Cwd::fastcwd()."/t");
return $self;
}
sub write {
my $self = shift;
my $args = {@_};
while(my($k,$v) = each %$args) {
$self->{$k} = $v;
}
my $base = $self->{base};
#XXX this sucks, find a better way
$Apache::httpd_conf::BaseDir = $base;
unless (-d "$base/conf") {
for (qw(conf logs docs perl)) {
File::Path::mkpath("$base/$_", 0, 0755);
}
}
my $fh = IO::File->new(">$base/conf/httpd.conf") or
die "can't open $base/conf/httpd.conf $!";
print $fh "PerlPassEnv PERL5LIB\n";
print $fh "<Perl>\n";
print $fh "BEGIN { \$Apache::httpd_conf::BaseDir = '$base'; }\n";
print $fh "use ", __PACKAGE__, "();\n";
print $fh "</Perl>\n";
while(my($k,$v) = each %$self) {
next unless $k =~ /^[A-Z]/;
no strict;
${"Apache::ReadConfig::".$k} = $v;
print $fh "$k $v\n";
}
print $fh "\n";
$fh->close;
}
sub server_start {
my $self = shift;
my @args = ();
my $args = {catch_sig => 1};
my $know_where = 0;
my %not_for_httpd = map { $_,1 } qw{httpd catch_sig};
do {
++$know_where if /^-(d|f)/;
if($not_for_httpd{$_}) {
$args->{$_} = shift;
}
else {
push @args, $_ if $_;
}
} while $_ = shift;
my $httpd = $args->{httpd} ||
prompt("where is your httpd?", "/opt/www/apache/httpd");
push @args, "-d" => $Apache::httpd_conf::BaseDir unless $know_where;
$self->catch_signals if $args->{catch_sig};
system "$httpd @args &";
}
sub pid {
my $self = shift;
my $pid_file = join "/", $self->{base}, $self->PidFile;
my $fh = IO::File->new($pid_file) or
die "can't open $pid_file $!\n";
chomp(my $pid = <$fh>);
return $pid;
}
sub server_stop {
kill 9, shift->pid;
}
sub server_url {
no strict;
require URI::URL;
my $url = URI::URL->new();
$url->scheme('http');
$url->host($Apache::ReadConfig::ServerName || "localhost");
$url->port($Apache::ReadConfig::Port || 80);
return $url;
}
sub catch_signals {
my $self = shift;
$SIG{INT} = $SIG{__DIE__} =
sub { print "stopping httpd\n"; $self->server_stop; exit(); }
}
sub prompt {
my($mess,$def) = @_;
print "$mess [$def]";
STDIN->untaint;
chomp(my $ans = <STDIN>);
$ans || $def;
}
sub AUTOLOAD {
my $self = shift;
my $name = (split "::", $AUTOLOAD)[-1];
my $val = shift || "";
my $retval = ${$Apache::ReadConfig::{$name}};
${$Apache::ReadConfig::{$name}} = $val if $val;
return $retval;
}
sub DESTROY {}
package Apache::ReadConfig;
no strict;
use subs qw(prompt);
*prompt = \&Apache::httpd_conf::prompt;
my $dir = $Apache::httpd_conf::BaseDir || "";
unless ($dir) {
my $cwd = Cwd::fastcwd();
for ($cwd, "$cwd/t") {
$dir = $_, last if -d "$_/logs";
}
}
my $Is_Win32 = ($^O eq "MSWin32");
$ServerRoot = $dir;
my $startup = "$ServerRoot/startup.pl";
if(-e $startup) {
push @PerlRequire, $startup;
}
$User = $Is_Win32 ? "nobody" : (getpwuid($>) || $>);
$Group = $Is_Win32 ? "nogroup" : (getgrgid($)) || $));
if($User eq "root") {
my $other = (getpwnam('nobody'))[0];
$User = $other if $other;
}
if($User eq "root") {
print "Cannot run tests as User `$User'\n";
$User = prompt "Which User?", "nobody";
$Group = prompt "Which Group?", $Group;
}
#print "Will run tests as User: '$User' Group: '$Group'\n";
$Port = 8529;
$DocumentRoot = $dir ? "$dir/docs" : "docs";
$ServerName = "localhost";
@Alias = () unless @Alias;
for (qw(/perl /cgi-bin)) {
push @Alias, [$_ => $dir ? "$dir/perl" : "perl"];
}
my @mod_perl = (
SetHandler => "perl-script",
PerlHandler => "Apache::Registry",
Options => "+ExecCGI",
);
push @AddType, ["text/x-server-parsed-html" => ".shtml"];
$Location{"/perl"} = {
@mod_perl,
};
$Location{"/cgi-bin"} = {
SetHandler => "cgi-script",
Options => "+ExecCGI",
};
$Location{"/perl-status"} = {
SetHandler => "perl-script",
PerlHandler => "Apache::Status",
};
for (qw(status info)) {
$Location{"/server-$_"} = {
SetHandler => "server-$_",
};
}
$ErrorLog = "logs/error_log";
$PidFile = "logs/httpd.pid";
$LockFile = "logs/lock";
for my $sym (
qw{
ResourceConfig AccessConfig TypesConfig TransferLog ScoreBoardFile
}
)
{
$$sym = "/dev/null";
}
while (my($k,$v) = each %Apache::ReadConfig::) {
$$k ||= $v if defined $$k; #avoid -w warnings
}
1;
__END__
=head1 NAME
Apache::httpd_conf - Generate an httpd.conf file
=head1 SYNOPSIS
use Apache::httpd_conf ();
Apache::httpd_conf->write(Port => 8888);
=head1 DESCRIPTION
The Apache::httpd_conf module will generate a tiny httpd.conf file,
which pulls itself back in via a <Perl> section. Any additional
arguments passed to the C<write> method will be added to the generated
httpd.conf file, and will override those defaults set in the <Perl>
section. This module is handy mostly for starting httpd servers to
test mod_perl scripts and modules.
=head1 AUTHOR
Doug MacEachern
=head1 SEE ALSO
mod_perl(3), Apache::PerlSections(3)
=cut