Alice

 view release on metacpan or  search on metacpan

lib/Alice/HTTP/Server.pm  view on Meta::CPAN

  builder => "_build_httpd",
);

has ping => (
  is  => 'rw',
  lazy => 1,
  default => sub {
    my $self = shift;
    AE::timer 1, 5, sub {
      $self->app->ping;
    };
  },
);

has port => (
  is => 'ro',
  default => 8080,
);

has address => (
  is => 'ro',
  default => "127.0.0.1",
);

has session => (
  is => 'ro'
);

has assets => (
  is => 'ro',
  required => 1,
);

my $url_handlers = [
  [ "say"          => "handle_message" ],
  [ "stream"       => "setup_xhr_stream" ],
  [ "wsstream"     => "setup_ws_stream" ],
  [ ""             => "send_index" ],
  [ "safe"         => "send_safe_index" ],
  [ "tabs"         => "tab_order" ],
  [ "savetabsets"  => "save_tabsets" ],
  [ "serverconfig" => "server_config" ],
  [ "save"         => "save_config" ],
  [ "login"        => "login" ],
  [ "logout"       => "logout" ],
  [ "export"       => "export_config" ],
];

sub url_handlers { return $url_handlers }

sub BUILD {
  my $self = shift;
  $self->httpd;
  $self->ping;
}

sub _build_httpd {
  my $self = shift;
  my $httpd;

  # eval in case server can't bind port
  eval {
    $httpd = Fliggy::Server->new(
      host => $self->address,
      port => $self->port,
    );
    $httpd->register_service(
      builder {
        enable "Session",
          store => $self->session,
          state => Plack::Session::State::Cookie->new(expires => 60 * 60 * 24 * 7);
        enable "Static", path => qr{^/static/}, root => $self->assets;
        enable "+Alice::HTTP::WebSocket";
        sub {
          my $env = shift;
          return sub {$self->dispatch($env, shift)}
        }
      }
    );
  };

  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;



( run in 2.430 seconds using v1.01-cache-2.11-cpan-2398b32b56e )