File Coverage

blib/lib/Gantry/Server.pm
Criterion Covered Total %
statement 18 86 20.9
branch 0 12 0.0
condition 0 13 0.0
subroutine 6 19 31.5
pod 9 9 100.0
total 33 139 23.7


line stmt bran cond sub pod time code
1             package Gantry::Server;
2 1     1   583 use strict; use warnings;
  1     1   2  
  1         26  
  1         4  
  1         2  
  1         28  
3              
4 1     1   4 use base qw( HTTP::Server::Simple::CGI );
  1         1  
  1         822  
5              
6 1     1   31639 use Symbol;
  1         3  
  1         909  
7              
8             my $engine_object;
9             my $net_server;
10              
11             sub set_engine_object {
12 0     0 1   my $self = shift;
13 0           $engine_object = shift;
14             }
15              
16             sub set_net_server {
17 0     0 1   my $self = shift;
18 0           $net_server = shift;
19             }
20              
21             sub handler {
22 0     0 1   my $self = shift;
23              
24 0           eval { $self->handle_request() };
  0            
25 0 0         if ( $@ ) {
26 0           warn "$@\n";
27             }
28             }
29              
30             sub handle_request_test_xml {
31 0     0 1   my ( $self, $location, $xml ) = @_;
32              
33 0           $engine_object->{__POST_BODY__} = $xml;
34 0           $ENV{ CONTENT_LENGTH } = 0;
35 0           $ENV{ REQUEST_METHOD } = 'POST';
36 0           $ENV{ URI } = $location;
37 0           $ENV{ PATH_INFO } = $location;
38              
39 0           return $self->_test_helper();
40             }
41              
42             sub handle_request_test_post {
43 0     0 1   my ( $self, $request ) = @_;
44              
45 0           my $method = 'POST'; # always GET for tests
46 0           $request =~ s/^(POST|GET)\://;
47            
48 0           my( $uri, $args ) = split( /\?/, $request );
49            
50 0   0       $ENV{PATH_INFO} = $uri || $request;
51 0           $ENV{REQUEST_METHOD} = $method;
52 0           $ENV{CONTENT_LENGTH} = 0;
53 0 0         $ENV{QUERY_STRING} = ( defined $args ? $args : '' );
54 0           $ENV{SCRIPT_NAME} = "";
55              
56 0           return $self->_test_helper();
57             }
58              
59             sub handle_request_test {
60 0     0 1   my ( $self, $request ) = @_;
61              
62 0           my $method = 'GET'; # always GET for tests
63 0           $request =~ s/^(POST|GET)\://;
64            
65 0           my( $uri, $args ) = split( /\?/, $request );
66            
67 0   0       $ENV{PATH_INFO} = $uri || $request;
68 0           $ENV{REQUEST_METHOD} = $method;
69 0           $ENV{CONTENT_LENGTH} = 0;
70 0 0         $ENV{QUERY_STRING} = ( defined $args ? $args : '' );
71 0           $ENV{SCRIPT_NAME} = "";
72              
73 0           return $self->_test_helper();
74             }
75              
76             sub _test_helper {
77 0     0     my $self = @_;
78              
79             # divert STDOUT to another handle that stores the returned data
80 0           my $out_handle = gensym;
81 0           my $out = tie *$out_handle, "Gantry::Server::Tier";
82 0           my $original_handle = select $out_handle;
83              
84             # dispatch to the gantry engine
85 0           my $status;
86 0           eval {
87 0           $status = $engine_object->dispatch();
88             };
89 0 0         if ( $@ ) {
90 0           return( '401', ( "($@)" . ( $out->get_output() ) ) );
91             }
92              
93 0           return( $status, $out->get_output() );
94            
95             }
96              
97             sub net_server {
98 0 0   0 1   $net_server ? $net_server : '';
99             }
100              
101             sub setup_server_url {
102 0   0 0 1   $ENV{SERVER_URL}
      0        
103             ||= (
104             "http://"
105             . ( $ENV{SERVER_NAME} || '' )
106             . ":" . $ENV{SERVER_PORT} . "/"
107             );
108             }
109              
110             sub handle_request {
111 0     0 1   my ( $self ) = @_;
112              
113             # divert STDOUT to another handle that stores the returned data
114 0           my $out_handle = gensym;
115 0           my $out = tie *$out_handle, "Gantry::Server::Tier";
116 0           my $original_handle = select $out_handle;
117              
118             # dispatch to the gantry engine
119 0           my $status;
120 0           eval {
121 0           $status = $engine_object->dispatch();
122             };
123 0 0         if ( $@ ) {
124 0           select $original_handle;
125 0           print <<"EO_FAILURE_RESPONSE";
126             HTTP/1.0 401 Not Found
127             Content-type: text/html
128              
129            

Not Found

130             The requested URL $ENV{PATH_INFO} was not found on this server.
131            
132             $@
133             EO_FAILURE_RESPONSE
134 0           return;
135             }
136            
137 0           select $original_handle;
138              
139 0           print "HTTP/1.0 $status\n" . $out->get_output();
140              
141             }
142              
143             package Gantry::Server::Tier;
144 1     1   7 use strict;
  1         2  
  1         112  
145              
146             sub get_output {
147 0     0     my $self = shift;
148              
149 0   0       return $self->[1] || '';
150             }
151              
152             sub TIEHANDLE {
153 0     0     my $class = shift;
154 0           my $self = [ shift() ];
155              
156 0           return bless $self, $class;
157             }
158              
159             sub PRINT {
160 0     0     my $self = shift;
161              
162 1     1   5 no warnings;
  1         1  
  1         99  
163 0           $self->[1] .= join '', @_;
164             }
165              
166             1;
167              
168             =head1 NAME
169              
170             Gantry::Server - HTTP::Server::Simple::CGI subclass providing stand alone server
171              
172             =head1 SYNOPSIS
173              
174             #!/usr/bin/perl
175             use strict;
176              
177             use Gantry::Server;
178              
179             use lib '/home/myhome/lib';
180              
181             use YourApp qw{ -Engine=CGI -TemplateEngine=Default };
182              
183             my $cgi_engine = Gantry::Engine::CGI->new();
184             $cgi_engine->add_location( '/', 'YourApp' );
185              
186             my $server = Gantry::Server->new();
187             # pass a port number to the above constructor if you don't want 8080.
188              
189             $server->set_engine_object( $cgi_engine );
190             $server->run();
191              
192             =head1 DESCRIPTION
193              
194             This module subclasses HTTP::Server::Simple::CGI to provide a stand
195             alone server for any Gantry app. Pretend you are deploying to a CGI
196             environment, but replace
197              
198             $cgi_engine->dispatch();
199              
200             with
201              
202             use Gantry::Server;
203              
204             my $server = Gantry::Server->new();
205             $server->set_engine_object( $cgi_engine );
206             $server->run();
207              
208             Note that you must call set_engine_object before calling run, and you
209             must pass it a valid Gantry::Engine::CGI object with the proper
210             locations and config definitions.
211              
212             By default, your server will start on port 8080. If you want a different
213             port, pass it to the constructor. You can generate the above script,
214             with port control, in bigtop by doing this in your config section:
215              
216             config {
217             engine CGI;
218             CGI Gantry { with_server 1; }
219             #...
220             }
221             app YourApp {
222             #...
223             }
224              
225             =head1 METHODS
226              
227             =over 4
228              
229             =item set_engine_object
230              
231             You must call this before calling run. Pass it a Gantry::Engine::CGI object.
232              
233             =item run
234              
235             This starts the server and never returns.
236              
237             =item handler
238              
239             This method overrides the parent version to avoid taking form parameters
240             prematurely.
241              
242             =item handle_request
243              
244             This method functions as a little web server processing http requests
245             (but it leans heavily on HTTP::Server::Simple::CGI).
246              
247             =item handle_request_test
248              
249             This method pretends to be a web server, but only handles a single request
250             before returning. This is useful for testing your Gantry app without
251             having to use sockets.
252              
253             =item handle_request_test_post
254              
255             This is the same as handle_request_test, but it treats the request as a POST.
256             This is mainly used for form testing.
257              
258             =item handle_request_test_xml
259              
260             This method is like C, but for SOAP packets. Call
261             it with the location you want to hit and the XML packet to PUT there.
262             Returns whatever the server returns.
263              
264             =item net_server
265              
266             Retrieves the defined Net::Sever engine type
267              
268             =item set_net_server
269              
270             optionaly you can set a Net::Sever engine type ( see Net::Server ).
271              
272             $server->set_net_server( 'Net::Server::PreForkSimple' );
273              
274             =item setup_server_url
275              
276             Builds and sets the SERVER_URL environment variable.
277              
278             =back
279              
280             =head1 AUTHOR
281              
282             Phil Crow
283              
284             =head1 COPYRIGHT and LICENSE
285              
286             Copyright (c) 2006, Phil Crow.
287              
288             This library is free software; you can redistribute it and/or modify
289             it under the same terms as Perl itself, either Perl version 5.8.6 or,
290             at your option, any later version of Perl 5 you may have available.
291              
292             =cut