WebGUI.pm as subclass of Plack::Component
This commit is contained in:
parent
5122518652
commit
ff2a36026a
2 changed files with 70 additions and 88 deletions
154
lib/WebGUI.pm
154
lib/WebGUI.pm
|
|
@ -20,16 +20,17 @@ our $STATUS = 'beta';
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use MIME::Base64 ();
|
use Moose;
|
||||||
|
use MooseX::NonMoose;
|
||||||
|
|
||||||
use WebGUI::Config;
|
use WebGUI::Config;
|
||||||
use WebGUI::Pluggable;
|
use WebGUI::Pluggable;
|
||||||
use WebGUI::Session;
|
|
||||||
use WebGUI::User;
|
|
||||||
use WebGUI::Session::Request;
|
|
||||||
use WebGUI::Paths;
|
use WebGUI::Paths;
|
||||||
use Moose;
|
|
||||||
use Try::Tiny;
|
use Try::Tiny;
|
||||||
|
|
||||||
|
extends 'Plack::Component';
|
||||||
|
|
||||||
=head1 NAME
|
=head1 NAME
|
||||||
|
|
||||||
Package WebGUI
|
Package WebGUI
|
||||||
|
|
@ -48,92 +49,73 @@ These subroutines are available from this package:
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
has site => ( is => 'ro', isa => 'Str', default => 'dev.localhost.localdomain.conf' );
|
has config => (
|
||||||
has config => ( is => 'rw', isa => 'WebGUI::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 {
|
# Each web request results in a call to this sub
|
||||||
my $orig = shift;
|
sub call {
|
||||||
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 {
|
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
|
my $env = shift;
|
||||||
|
|
||||||
# Instantiate the WebGUI::Config object
|
# Use the PSGI callback style response, which allows for nice things like
|
||||||
my $config = WebGUI::Config->new( $self->site );
|
# delayed response/streaming body (server push). For now we just use this for
|
||||||
$self->config($config);
|
# unbuffered response writing
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
return sub {
|
return sub {
|
||||||
my $env = shift;
|
my $responder = shift;
|
||||||
|
my $session = $env->{'webgui.session'}
|
||||||
# Use the PSGI callback style response, which allows for nice things like
|
or die 'Missing WebGUI Session - check WebGUI::Middleware::Session';
|
||||||
# delayed response/streaming body (server push). For now we just use this for
|
|
||||||
# unbuffered response writing
|
# Handle the request
|
||||||
return sub {
|
handle($session);
|
||||||
my $responder = shift;
|
|
||||||
my $session = $env->{'webgui.session'} or die 'Missing WebGUI Session - check WebGUI::Middleware::Session';
|
# Construct the PSGI response
|
||||||
|
my $response = $session->response;
|
||||||
# Handle the request
|
my $psgi_response = $response->finalize;
|
||||||
handle($session);
|
|
||||||
|
# See if the content handler is doing unbuffered response writing
|
||||||
# Construct the PSGI response
|
if ( $response->streaming ) {
|
||||||
my $response = $session->response;
|
try {
|
||||||
my $psgi_response = $response->finalize;
|
# Ask PSGI server for a streaming writer object by returning only the first
|
||||||
|
# two elements of the array reference
|
||||||
# See if the content handler is doing unbuffered response writing
|
my $writer = $responder->( [ $psgi_response->[0], $psgi_response->[1] ] );
|
||||||
if ( $response->streaming ) {
|
|
||||||
|
# Store the writer object in the WebGUI::Session::Response object
|
||||||
try {
|
$response->writer($writer);
|
||||||
# Ask PSGI server for a streaming writer object by returning only the first
|
|
||||||
# two elements of the array reference
|
# Now call the callback that does the streaming
|
||||||
my $writer = $responder->( [ $psgi_response->[0], $psgi_response->[1] ] );
|
$response->streamer->($session);
|
||||||
|
|
||||||
# Store the writer object in the WebGUI::Session::Response object
|
# And finally, clean up
|
||||||
$response->writer($writer);
|
$writer->close;
|
||||||
|
|
||||||
# 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);
|
|
||||||
}
|
}
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,10 +45,10 @@ builder {
|
||||||
# This one uses the Session object, so it comes after WebGUI::Middleware::Session
|
# This one uses the Session object, so it comes after WebGUI::Middleware::Session
|
||||||
mount $config->get('uploadsURL') => builder {
|
mount $config->get('uploadsURL') => builder {
|
||||||
enable '+WebGUI::Middleware::WGAccess';
|
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
|
# Return the app
|
||||||
mount '/' => $wg->to_app;
|
mount '/' => $wg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue