Commit | Line | Data |
5c33dda5 |
1 | package Web::Simple::Application; |
2 | |
8bd060f4 |
3 | use Moo; |
5c33dda5 |
4 | |
876e62e1 |
5 | has 'config' => ( |
6 | is => 'ro', |
7 | default => sub { |
8 | my ($self) = @_; |
9 | +{ $self->default_config } |
10 | }, |
11 | trigger => sub { |
12 | my ($self, $value) = @_; |
13 | my %default = $self->default_config; |
14 | my @not = grep !exists $value->{$_}, keys %default; |
15 | @{$value}{@not} = @default{@not}; |
16 | } |
17 | ); |
5c33dda5 |
18 | |
445b3ea0 |
19 | sub default_config { () } |
39119082 |
20 | |
445b3ea0 |
21 | has '_dispatcher' => (is => 'lazy'); |
5c33dda5 |
22 | |
445b3ea0 |
23 | sub _build__dispatcher { |
24 | my $self = shift; |
25 | require Web::Dispatch; |
26 | require Web::Simple::DispatchNode; |
27 | my $final = $self->_build_final_dispatcher; |
28 | Web::Dispatch->new( |
29 | app => sub { $self->dispatch_request(@_), $final }, |
30 | node_class => 'Web::Simple::DispatchNode', |
31 | node_args => { app_object => $self } |
32 | ); |
5c33dda5 |
33 | } |
34 | |
3583ca04 |
35 | sub _build_final_dispatcher { |
4ed4fb42 |
36 | [ 404, [ 'Content-type', 'text/plain' ], [ 'Not found' ] ] |
5c33dda5 |
37 | } |
38 | |
5c33dda5 |
39 | sub run_if_script { |
b9e047ef |
40 | # ->to_psgi_app is true for require() but also works for plackup |
445b3ea0 |
41 | return $_[0]->to_psgi_app if caller(1); |
e27ab5c5 |
42 | my $self = ref($_[0]) ? $_[0] : $_[0]->new; |
5c33dda5 |
43 | $self->run(@_); |
44 | } |
45 | |
913a9cf9 |
46 | sub _run_cgi { |
5c33dda5 |
47 | my $self = shift; |
e27ab5c5 |
48 | require Plack::Server::CGI; |
b9e047ef |
49 | Plack::Server::CGI->run($self->to_psgi_app); |
d3a61609 |
50 | } |
51 | |
e27ab5c5 |
52 | sub _run_fcgi { |
53 | my $self = shift; |
54 | require Plack::Server::FCGI; |
b9e047ef |
55 | Plack::Server::FCGI->run($self->to_psgi_app); |
e27ab5c5 |
56 | } |
57 | |
445b3ea0 |
58 | sub to_psgi_app { |
bc57805c |
59 | my $self = ref($_[0]) ? $_[0] : $_[0]->new; |
445b3ea0 |
60 | $self->_dispatcher->to_app; |
5c33dda5 |
61 | } |
62 | |
913a9cf9 |
63 | sub run { |
64 | my $self = shift; |
e27ab5c5 |
65 | if ($ENV{PHP_FCGI_CHILDREN} || $ENV{FCGI_ROLE} || $ENV{FCGI_SOCKET_PATH}) { |
66 | return $self->_run_fcgi; |
67 | } elsif ($ENV{GATEWAY_INTERFACE}) { |
2514ad17 |
68 | return $self->_run_cgi; |
913a9cf9 |
69 | } |
d104fb1d |
70 | unless (@ARGV && $ARGV[0] =~ m{^/}) { |
db2899c3 |
71 | return $self->_run_cli(@ARGV); |
d104fb1d |
72 | } |
73 | |
74 | my $path = shift @ARGV; |
913a9cf9 |
75 | |
913a9cf9 |
76 | require HTTP::Request::Common; |
e27ab5c5 |
77 | require Plack::Test; |
913a9cf9 |
78 | local *GET = \&HTTP::Request::Common::GET; |
79 | |
80 | my $request = GET($path); |
e27ab5c5 |
81 | my $response; |
b9e047ef |
82 | Plack::Test::test_psgi($self->to_psgi_app, sub { $response = shift->($request) }); |
e27ab5c5 |
83 | print $response->as_string; |
913a9cf9 |
84 | } |
85 | |
d104fb1d |
86 | sub _run_cli { |
87 | my $self = shift; |
88 | die $self->_cli_usage; |
89 | } |
90 | |
91 | sub _cli_usage { |
92 | "To run this script in CGI test mode, pass a URL path beginning with /:\n". |
93 | "\n". |
94 | " $0 /some/path\n". |
95 | " $0 /\n" |
96 | } |
97 | |
5c33dda5 |
98 | 1; |
32d29dcd |
99 | |
100 | =head1 NAME |
101 | |
102 | Web::Simple::Application - A base class for your Web-Simple applications |
103 | |
104 | =head1 DESCRIPTION |
105 | |
106 | This is a base class for your L<Web::Simple> application. You probably don't |
107 | need to construct this class yourself, since L<Web::Simple> does the 'heavy |
108 | lifting' for you in that regards. |
109 | |
110 | =head1 METHODS |
111 | |
112 | This class exposes the follow public methods. |
113 | |
114 | =head2 default_config |
115 | |
116 | Provide configuration information to your application, for example: |
117 | |
118 | sub default_config { |
119 | ( |
120 | title => 'Bloggery', |
121 | posts_dir => $FindBin::Bin.'/posts', |
122 | ); |
123 | } |
124 | |
125 | Now, C<$self> will have an attribute C<config> which will be set to a HashRef |
126 | containing keys 'title' and 'posts_dir'. |
127 | |
128 | =head2 run_if_script |
129 | |
130 | In the case where you wish to run you L<Web::Simple> based application as a |
131 | stand alone CGI application, you can simple do: |
132 | |
133 | ## my_web_simple_app.pl |
134 | use MyWebSimpleApp::Web; |
135 | MyWebSimpleApp::Web->run_if_script. |
136 | |
137 | Or (even more simply) just inline the entire application: |
138 | |
139 | ## my_web_simple_app.pl |
140 | #!/usr/bin/env perl |
141 | use Web::Simple 'HelloWorld'; |
142 | |
143 | { |
144 | package HelloWorld; |
145 | |
146 | sub dispatch_request { |
147 | sub (GET) { |
148 | [ 200, [ 'Content-type', 'text/plain' ], [ 'Hello world!' ] ] |
149 | }, |
150 | sub () { |
151 | [ 405, [ 'Content-type', 'text/plain' ], [ 'Method not allowed' ] ] |
152 | } |
153 | } |
154 | } |
155 | |
156 | HelloWorld->run_if_script; |
157 | |
158 | =head2 to_psgi_app |
159 | |
160 | Given a L<Web::Simple> application root namespace, return it in a form suitable |
161 | to run in inside a L<Plack> container, or in L<Plack::Builder> or in a C<*.psgi> |
162 | file: |
163 | |
164 | ## app.psgi |
165 | use strictures 1; |
166 | use Plack::Builder; |
167 | use MyWebSimpleApp::Web; |
168 | |
169 | builder { |
170 | ## enable middleware |
171 | enable 'StackTrace'; |
172 | enable 'Debug'; |
173 | |
174 | ## return application |
175 | MyWebSimpleApp::Web->to_psgi_app; |
176 | }; |
177 | |
178 | This could be run via C<plackup>, etc. Please note the L<Plack::Builder> DSL |
179 | is optional, if you are enabling L<Plack::Middleware> internally in your |
180 | L<Web::Simple> application; your app.psgi could be as simple as: |
181 | |
182 | use MyWebSimpleApp::Web; |
183 | MyWebSimpleApp::Web->to_psgi_app; |
184 | |
185 | As always, mix and match the pieces you actually need and remember the |
186 | L<Web::Simple> philosophy of trying to keep it as minimal and simple as possible. |
187 | |
188 | =head2 run |
189 | |
190 | Used for running your application under stand-alone CGI and FCGI modes. Also |
191 | useful for testing: |
192 | |
193 | my $app = MyWebSimpleApp::Web->new; |
194 | my $c = HTTP::Request::AsCGI->new(@args)->setup; |
195 | $app->run; |
196 | |
197 | =head1 AUTHOR |
198 | |
199 | Matt S. Trout <mst@shadowcat.co.uk> |
200 | |
201 | =head1 CONTRIBUTORS |
202 | |
203 | None required yet. Maybe this module is perfect (hahahahaha ...). |
204 | |
205 | =head1 COPYRIGHT |
206 | |
207 | Copyright (c) 2009 the Web::Simple L</AUTHOR> and L</CONTRIBUTORS> |
208 | as listed above. |
209 | |
210 | =head1 LICENSE |
211 | |
212 | This library is free software and may be distributed under the same terms |
213 | as perl itself. |
214 | |
215 | =cut |