Alice
view release on metacpan or search on metacpan
lib/Alice/HTTP/Server.pm view on Meta::CPAN
$res->send;
}
# we have credentials
elsif (my $user = $req->param('username')
and my $pass = $req->param('password')) {
$self->authenticate($user, $pass, sub {
my $app = shift;
if ($app) {
$req->env->{"psgix.session"} = {
is_logged_in => 1,
username => $user,
userid => $app->user,
};
$res->redirect($dest);
}
else {
$req->env->{"psgix.session"}{is_logged_in} = 0;
$req->env->{"psgix.session.options"}{expire} = 1;
$res->content_type("text/html; charset=utf-8");
$res->body($self->render("login", $dest, "bad username or password"));
}
$res->send;
});
}
# render the login page
else {
$res->content_type("text/html; charset=utf-8");
$res->body($self->render("login", $dest));
$res->send;
}
}
sub logout {
my ($self, $req, $res) = @_;
$_->close for @{$self->app->streams};
if (!$self->auth_enabled) {
$res->redirect("/");
} else {
$req->env->{"psgix.session"}{is_logged_in} = 0;
$req->env->{"psgix.session.options"}{expire} = 1;
$res->redirect("/login");
}
$res->send;
}
sub setup_xhr_stream {
my ($self, $req, $res) = @_;
my $app = $self->app;
AE::log debug => "opening new stream";
$res->headers([@Alice::HTTP::Stream::XHR::headers]);
my $stream = Alice::HTTP::Stream::XHR->new(
writer => $res->writer,
start_time => $req->param('t'),
# android requires 4K updates to trigger loading event
min_bytes => $req->user_agent =~ /android/i ? 4096 : 0,
on_error => sub { $app->purge_disconnects },
);
$stream->send([$app->connect_actions]);
$app->add_stream($stream);
}
sub setup_ws_stream {
my ($self, $req, $res) = @_;
my $app = $self->app;
AE::log debug => "opening new websocket stream";
if (my $fh = $req->env->{'websocket.impl'}->handshake) {
my $stream = Alice::HTTP::Stream::WebSocket->new(
start_time => $req->param('t') || time,
fh => $fh,
on_read => sub { $app->handle_message(@_) },
on_error => sub { $app->purge_disconnects },
ws_version => $req->env->{'websocket.impl'}->version,
);
$stream->send([$app->connect_actions]);
$app->add_stream($stream);
}
else {
my $code = $req->env->{'websocket.impl'}->error_code;
$res->send([$code, ["Content-Type", "text/plain"], ["something broke"]]);
}
}
sub handle_message {
my ($self, $req, $res) = @_;
my $msg = $req->param('msg');
my $html = $req->param('html');
my $source = $req->param('source');
my $stream = $req->param('stream');
$self->app->handle_message({
msg => defined $msg ? $msg : "",
html => defined $html ? $html : "",
source => defined $source ? $source : "",
stream => defined $stream ? $stream : "",
});
$res->ok;
}
sub send_safe_index {
my ($self, $req, $res) = @_;
$req->parameters->{images} = "hide";
$req->parameters->{avatars} = "hide";
$self->send_index($req, $res);
}
sub send_index {
my ($self, $req, $res) = @_;
my $options = $self->merged_options($req);
my $app = $self->app;
$res->headers(["Content-type" => "text/html; charset=utf-8"]);
my $writer = $res->writer;
my @windows = $app->sorted_windows;
my @queue;
push @queue, sub {$app->render('index_head', @windows)};
for my $window (@windows) {
push @queue, sub {$app->render('window_head', $window)};
push @queue, sub {$app->render('window_footer', $window)};
}
push @queue, sub {
my $html = $app->render('index_footer', $options, @windows);
$app->config->first_run(0);
$app->config->write;
return $html;
};
my $idle_w; $idle_w = AE::idle sub {
if (my $cb = shift @queue) {
my $content = encode "utf8", $cb->();
$writer->write($content);
} else {
$writer->close;
undef $idle_w;
}
( run in 1.645 second using v1.01-cache-2.11-cpan-39bf76dae61 )