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 )