Alice
view release on metacpan or search on metacpan
lib/Alice/HTTP/Server.pm view on Meta::CPAN
AE::log(warn => $@) if $@;
return $httpd;
}
sub dispatch {
my ($self, $env, $cb) = @_;
my $req = Alice::HTTP::Request->new($env, $cb);
my $res = $req->new_response(200);
AE::log trace => $req->path;
if ($self->auth_enabled) {
unless ($req->path eq "/login" or $self->is_logged_in($req)) {
$self->auth_failed($req, $res);
return;
}
}
for my $handler (@{$self->url_handlers}) {
my $path = $handler->[0];
if ($req->path_info =~ /^\/$path\/?$/) {
my $method = $handler->[1];
$self->$method($req, $res);
return;
}
}
$self->template($req, $res);
}
sub auth_failed {
my ($self, $req, $res) = @_;
if ($req->path =~ m{^(/(?:safe)?)$}) {
$res->redirect("/login".($1 ? "?dest=$1" : ""));
$res->body("bai");
} else {
$res->status(401);
$res->body("unauthorized");
}
$res->send;
}
sub is_logged_in {
my ($self, $req) = @_;
my $session = $req->env->{"psgix.session"};
return $session->{is_logged_in};
}
sub login {
my ($self, $req, $res) = @_;
my $dest = $req->param("dest") || "/";
# no auth is required
if (!$self->auth_enabled) {
$res->redirect($dest);
$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]);
( run in 0.472 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )