1 package Web::Simple::Application;
4 use warnings FATAL => 'all';
7 package Web::Simple::Dispatcher;
11 and "$_[1]" =~ /\w+=[A-Z]/
12 and $_[1]->isa(__PACKAGE__);
17 ? $_[0]->{next} = $_[1]
22 $_[0]->{next} = $_[1];
27 my ($self, $env, @args) = @_;
28 my $next = $self->next;
29 if (my ($env_delta, @match) = $self->_match_against($env)) {
30 if (my ($result) = $self->_execute_with(@args, @match)) {
31 if ($self->_is_dispatcher($result)) {
32 $next = $result->set_next($next);
33 $env = { %$env, %$env_delta };
39 return $next->dispatch($env, @args);
43 return ({}, $_[1]) unless $_[0]->{match};
44 $_[0]->{match}->($_[1]);
53 my ($class, $data) = @_;
54 my $config = { $class->_default_config, %{($data||{})->{config}||{}} };
55 bless({ config => $config }, $class);
58 sub _default_config { () }
64 sub _construct_response_filter {
66 $_[0]->_build_dispatcher({
68 my ($d, $self, $env) = (shift, shift, shift);
69 $self->_run_with_self($code, $d->next->dispatch($env, $self, @_));
74 sub _construct_redispatch {
75 my ($self, $new_path) = @_;
76 $self->_build_dispatcher({
79 my ($self, $env) = @_;
80 $self->handle_request({ %{$env}, PATH_INFO => $new_path })
85 sub _dispatch_parser {
86 require Web::Simple::DispatchParser;
87 return Web::Simple::DispatchParser->new;
90 sub _setup_dispatchables {
91 my ($class, $dispatch_subs) = @_;
92 my $parser = $class->_dispatch_parser;
95 foreach my $dispatch_sub (@$dispatch_subs) {
96 my $proto = prototype $dispatch_sub;
99 ? $parser->parse_dispatch_specification($proto)
102 my $new = $class->_build_dispatcher({
105 shift->_run_with_self($dispatch_sub, @_)
109 $last = $last ? $last->next($new) : $new;
110 push @dispatchables, [ $matcher, $dispatch_sub ];
112 $last->next($class->_build_final_dispatcher);
115 *{"${class}::_dispatch_root"} = sub { $root };
119 sub _build_dispatcher {
120 bless($_[1], 'Web::Simple::Dispatcher');
123 sub _build_final_dispatcher {
124 shift->_build_dispatcher({
127 500, [ 'Content-type', 'text/plain' ],
128 [ 'The management apologises but we have no idea how to handle that' ]
135 my ($self, $env) = @_;
136 $self->_dispatch_root->dispatch($env, $self);
140 my ($self, $run, @args) = @_;
141 my $class = ref($self);
143 local *{"${class}::self"} = \$self;
148 return 1 if caller(1); # 1 so we can be the last thing in the file
150 my $self = $class->new;
156 require Web::Simple::HackedPlack;
157 Plack::Server::CGI->run(sub { $self->handle_request(@_) });
162 if ($ENV{GATEWAY_INTERFACE}) {
165 my $path = shift(@ARGV) or die "No path passed - use $0 / for root";
167 require HTTP::Request::AsCGI;
168 require HTTP::Request::Common;
169 local *GET = \&HTTP::Request::Common::GET;
171 my $request = GET($path);
172 my $c = HTTP::Request::AsCGI->new($request)->setup;
175 print $c->response->as_string;