/usr/local/CPAN/Pangloss/Pangloss/WebApp/Standalone.pm


package Pangloss::WebApp::Standalone;

use strict;
use warnings::register;

use File::Spec;
use HTTP::Daemon;
use Scalar::Util qw( weaken );

use base      qw( Pangloss::WebApp );
use accessors qw( port httpd connection old_dir );

our $VERSION  = ((require Pangloss::Version), $Pangloss::VERSION)[1];
our $REVISION = (split(/ /, ' $Revision: 1.3 $ '))[2];

#------------------------------------------------------------------------------
# Object initialization

sub init_tfactory {
    my $self = shift;
    # we chdir PG_HOME below
    $self->config->{PG_TEMPLATE_DIR} = File::Spec->catdir(qw( . web ));
    $self->SUPER::init_tfactory(@_);
}

#------------------------------------------------------------------------------
# Standalone server

sub event_loop {
    my $self = shift;

    $self->old_dir( File::Spec->rel2abs(File::Spec->curdir) );

    sub sig_handler {
	no warnings;
	my $sig = shift;
	$self->emit( "\ncaught sig $sig...\n" );
	$self->quit(1);
    }

    local %SIG;
    $SIG{INT}  = \&handler;
    $SIG{HUP}  = \&handler;
    $SIG{QUIT} = \&handler;

    chdir( $self->config->{PG_HOME} ) if $self->config->{PG_HOME};

    my $httpd = HTTP::Daemon->new(
				  LocalPort => $self->port,
				  Reuse     => 1,
				 ) || die "error starting http daemon: $!";

    $self->httpd( $httpd );
    weaken( $httpd ); # make sure server goes away on quit()

    $self->emit( "server running at http://localhost:" . $self->port . "\n" );

    while (my $conn = $httpd->accept()) {
	$self->connection( $conn );
	while (my $request = $conn->get_request) {
	    $self->handle_request( $request );
	}
    }

    $self->quit(0);
}

sub handle_request {
    my $self    = shift;
    my $request = shift;

    my $prod = $self->SUPER::handle_request( $request );

    my $response = $self->controller->store->get('HTTP::Response');

    # TODO: error handling here...

    $self->connection->send_response( $response );
    $self->emit( "sent response (" . length($response->content)
		 . " characters)\n" );

    $self->connection->close;	# keep-alive is messing up in Safari :-/

    return $self;
}

sub quit {
    my $self = shift;
    my $code = shift || 0;
    $self->emit( "shutting down server.\n" );
    $self->app( undef )
         ->httpd( undef );
    if (my $old_dir = $self->old_dir) {
	$self->emit( "cd'ing back to $old_dir\n" );
	chdir( $old_dir );
    }
    CORE::exit $code;
}

1;