diff --git a/lib/WebGUI.pm b/lib/WebGUI.pm index 88ead5ff6..613b5ccc4 100644 --- a/lib/WebGUI.pm +++ b/lib/WebGUI.pm @@ -20,16 +20,17 @@ our $STATUS = 'beta'; =cut use strict; -use MIME::Base64 (); +use Moose; +use MooseX::NonMoose; + use WebGUI::Config; use WebGUI::Pluggable; -use WebGUI::Session; -use WebGUI::User; -use WebGUI::Session::Request; use WebGUI::Paths; -use Moose; + use Try::Tiny; +extends 'Plack::Component'; + =head1 NAME Package WebGUI @@ -48,92 +49,73 @@ These subroutines are available from this package: =cut -has site => ( is => 'ro', isa => 'Str', default => 'dev.localhost.localdomain.conf' ); -has config => ( is => 'rw', isa => 'WebGUI::Config' ); +has config => ( + is => 'rw', + isa => 'WebGUI::Config', +); +has site => ( + is => 'ro', + isa => 'Str', + required => 1, + trigger => sub { + my ($self, $site) = @_; + my $config = WebGUI::Config->new( $site ); + $self->config($config); + }, +); -around BUILDARGS => sub { - my $orig = shift; - my $class = shift; - - # Make constructor work as: - # WebGUI->new( $site ) - # In addition to the more verbose: - # WebGUI->new( root => $root, site => $site ) - if (@_ eq 1) { - return $class->$orig(site => $_[0] ); - } else { - return $class->$orig(@_); - } -}; - -sub BUILD { +# Each web request results in a call to this sub +sub call { my $self = shift; + my $env = shift; - # Instantiate the WebGUI::Config object - my $config = WebGUI::Config->new( $self->site ); - $self->config($config); -} - -sub to_app { - my $self = shift; - return $self->{psgi_app} ||= $self->compile_psgi_app; -} - -sub compile_psgi_app { - my $self = shift; - - # WebGUI is a PSGI app is a Perl code reference. Let's create one. - # Each web request results in a call to this sub + # Use the PSGI callback style response, which allows for nice things like + # delayed response/streaming body (server push). For now we just use this for + # unbuffered response writing return sub { - my $env = shift; - - # Use the PSGI callback style response, which allows for nice things like - # delayed response/streaming body (server push). For now we just use this for - # unbuffered response writing - return sub { - my $responder = shift; - my $session = $env->{'webgui.session'} or die 'Missing WebGUI Session - check WebGUI::Middleware::Session'; - - # Handle the request - handle($session); - - # Construct the PSGI response - my $response = $session->response; - my $psgi_response = $response->finalize; - - # See if the content handler is doing unbuffered response writing - if ( $response->streaming ) { - - try { - # Ask PSGI server for a streaming writer object by returning only the first - # two elements of the array reference - my $writer = $responder->( [ $psgi_response->[0], $psgi_response->[1] ] ); - - # Store the writer object in the WebGUI::Session::Response object - $response->writer($writer); - - # Now call the callback that does the streaming - $response->streamer->($session); - - # And finally, clean up - $writer->close; - - } catch { - if ($response->writer) { - # Response has already been started, so log error and close writer - $session->request->TRACE("Error detected after streaming response started"); - $response->writer->close; - } else { - $responder->( [ 500, [ 'Content-Type' => 'text/plain' ], [ "Internal Server Error" ] ] ); - } - - } - } else { - # Not streaming, so immediately tell the callback to return - # the response. In the future we could use an Event framework here - # to make this a non-blocking delayed response. - $responder->($psgi_response); + my $responder = shift; + my $session = $env->{'webgui.session'} + or die 'Missing WebGUI Session - check WebGUI::Middleware::Session'; + + # Handle the request + handle($session); + + # Construct the PSGI response + my $response = $session->response; + my $psgi_response = $response->finalize; + + # See if the content handler is doing unbuffered response writing + if ( $response->streaming ) { + try { + # Ask PSGI server for a streaming writer object by returning only the first + # two elements of the array reference + my $writer = $responder->( [ $psgi_response->[0], $psgi_response->[1] ] ); + + # Store the writer object in the WebGUI::Session::Response object + $response->writer($writer); + + # Now call the callback that does the streaming + $response->streamer->($session); + + # And finally, clean up + $writer->close; } + catch { + if ($response->writer) { + # Response has already been started, so log error and close writer + $session->request->TRACE("Error detected after streaming response started"); + $response->writer->close; + } + else { + $responder->( [ 500, [ 'Content-Type' => 'text/plain' ], [ "Internal Server Error" ] ] ); + } + }; + } + else { + # Not streaming, so immediately tell the callback to return + # the response. In the future we could use an Event framework here + # to make this a non-blocking delayed response. + $responder->($psgi_response); } }; } diff --git a/var/site.psgi b/var/site.psgi index 2db3bdf59..0ee062f69 100644 --- a/var/site.psgi +++ b/var/site.psgi @@ -45,10 +45,10 @@ builder { # This one uses the Session object, so it comes after WebGUI::Middleware::Session mount $config->get('uploadsURL') => builder { enable '+WebGUI::Middleware::WGAccess'; - Plack::App::File->new(root => $config->get('uploadsPath'))->to_app; + Plack::App::File->new(root => $config->get('uploadsPath')); }; # Return the app - mount '/' => $wg->to_app; + mount '/' => $wg; };