File Coverage

blib/lib/Mojo/Server.pm
Criterion Covered Total %
statement 51 57 89.4
branch 11 18 61.1
condition 2 3 66.6
subroutine 13 14 92.8
pod 6 6 100.0
total 83 98 84.6


line stmt bran cond sub pod time code
1             package Mojo::Server;
2 57     57   534 use Mojo::Base 'Mojo::EventEmitter';
  57         158  
  57         446  
3              
4 57     57   740 use Carp qw(croak);
  57         248  
  57         4038  
5 57     57   1110 use Mojo::File qw(path);
  57         146  
  57         3337  
6 57     57   2134 use Mojo::Loader qw(load_class);
  57         322  
  57         4266  
7 57     57   380 use Mojo::Util qw(md5_sum);
  57         158  
  57         2984  
8 57     57   10405 use POSIX ();
  57         135460  
  57         3546  
9 57     57   386 use Scalar::Util qw(blessed);
  57         155  
  57         77984  
10              
11             has app => sub { shift->build_app('Mojo::HelloWorld') };
12             has reverse_proxy => sub { $ENV{MOJO_REVERSE_PROXY} || !!@{shift->trusted_proxies} };
13             has trusted_proxies => sub { [split /\s*,\s*/, ($ENV{MOJO_TRUSTED_PROXIES} // '')] };
14              
15             our @ARGS_OVERRIDE;
16              
17             sub build_app {
18 38     38 1 121 my ($self, $app) = (shift, shift);
19 38         263 local $ENV{MOJO_EXE};
20 38 100       194 return $self->app($app->new(@_))->app unless my $e = load_class $app;
21 1 50       17 die ref $e ? $e : qq{Can't find application class "$app" in \@INC. (@INC)\n};
22             }
23              
24             sub build_tx {
25 1031     1031 1 2078 my $self = shift;
26 1031         4571 my $tx = $self->app->build_tx;
27 1031         3039 push @{$tx->req->trusted_proxies}, @{$self->trusted_proxies};
  1031         4014  
  1031         4107  
28 1031 100       4447 $tx->req->reverse_proxy(1) if $self->reverse_proxy;
29 1031         4611 return $tx;
30             }
31              
32             sub daemonize {
33              
34             # Fork and kill parent
35 0 0   0 1 0 die "Can't fork: $!" unless defined(my $pid = fork);
36 0 0       0 exit 0 if $pid;
37 0 0       0 POSIX::setsid == -1 and die "Can't start a new session: $!";
38              
39             # Close filehandles
40 0         0 open STDIN, '<', '/dev/null';
41 0         0 open STDOUT, '>', '/dev/null';
42 0         0 open STDERR, '>&', STDOUT;
43             }
44              
45             sub load_app {
46 18 100   18 1 125 my ($self, $path, @args) = (shift, shift, ref $_[0] ? %{shift()} : @_);
  1         6  
47              
48             # Clean environment (reset FindBin defensively)
49             {
50 18         38 local $0 = $path = path($path)->to_abs->to_string;
  18         75  
51 18         2622 require FindBin;
52 18         6502 FindBin->again;
53 18         3855 local @ENV{qw(MOJO_APP_LOADER MOJO_EXE)} = (1, undef);
54 18         77 local @ARGS_OVERRIDE = @args;
55              
56             # Try to load application from script into sandbox
57 18         3246 my $app = eval sprintf <<'END_CODE', md5_sum($path);
58             package Mojo::Server::Sandbox::%s;
59             do $path or die $@ || $! || "$path did not return a true value";
60             END_CODE
61 18 100       355 die qq{Can't load application from file "$path": $@} if $@;
62 17 100 66     207 die qq{File "$path" did not return an application object.\n} unless blessed $app && $app->can('handler');
63 16         95 $self->app($app);
64             };
65 16         215 FindBin->again;
66              
67 16         3831 return $self->app;
68             }
69              
70             sub new {
71 266     266 1 38512 my $self = shift->SUPER::new(@_);
72 266     1031   3616 $self->on(request => sub { shift->app->handler(shift) });
  1031         3894  
73 266         1267 return $self;
74             }
75              
76 1     1 1 1341 sub run { croak 'Method "run" not implemented by subclass' }
77              
78             1;
79              
80             =encoding utf8
81              
82             =head1 NAME
83              
84             Mojo::Server - HTTP/WebSocket server base class
85              
86             =head1 SYNOPSIS
87              
88             package Mojo::Server::MyServer;
89             use Mojo::Base 'Mojo::Server', -signatures;
90              
91             sub run ($self) {
92              
93             # Get a transaction
94             my $tx = $self->build_tx;
95              
96             # Emit "request" event
97             $self->emit(request => $tx);
98             }
99              
100             =head1 DESCRIPTION
101              
102             L is an abstract base class for HTTP/WebSocket servers and server interfaces, like L,
103             L, L, L, L and
104             L.
105              
106             =head1 EVENTS
107              
108             L inherits all events from L and can emit the following new ones.
109              
110             =head2 request
111              
112             $server->on(request => sub ($server, $tx) {...});
113              
114             Emitted when a request is ready and needs to be handled.
115              
116             $server->on(request => sub ($server, $tx) {
117             $tx->res->code(200);
118             $tx->res->headers->content_type('text/plain');
119             $tx->res->body('Hello World!');
120             $tx->resume;
121             });
122              
123             =head1 ATTRIBUTES
124              
125             L implements the following attributes.
126              
127             =head2 app
128              
129             my $app = $server->app;
130             $server = $server->app(MojoSubclass->new);
131              
132             Application this server handles, defaults to a L object.
133              
134             =head2 reverse_proxy
135              
136             my $bool = $server->reverse_proxy;
137             $server = $server->reverse_proxy($bool);
138              
139             This server operates behind a reverse proxy, defaults to the value of the C environment variable
140             or true if L is not empty.
141              
142             =head2 trusted_proxies
143              
144             my $proxies = $server->trusted_proxies;
145             $server = $server->trusted_proxies(['10.0.0.0/8', '127.0.0.1', '172.16.0.0/12', '192.168.0.0/16', 'fc00::/7']);
146              
147             This server expects requests from trusted reverse proxies, defaults to the value of the C
148             environment variable split on commas with optional whitespace. These proxies should be addresses or networks in CIDR
149             form.
150              
151             =head1 METHODS
152              
153             L inherits all methods from L and implements the following new ones.
154              
155             =head2 build_app
156              
157             my $app = $server->build_app('MyApp');
158             my $app = $server->build_app('MyApp', log => Mojo::Log->new);
159             my $app = $server->build_app('MyApp', {log => Mojo::Log->new});
160              
161             Build application from class and assign it to L.
162              
163             =head2 build_tx
164              
165             my $tx = $server->build_tx;
166              
167             Let application build a transaction.
168              
169             =head2 daemonize
170              
171             $server->daemonize;
172              
173             Daemonize server process.
174              
175             =head2 load_app
176              
177             my $app = $server->load_app('/home/sri/myapp.pl');
178             my $app = $server->load_app('/home/sri/myapp.pl', log => Mojo::Log->new);
179             my $app = $server->load_app('/home/sri/myapp.pl', {log => Mojo::Log->new});
180              
181             Load application from script and assign it to L.
182              
183             say Mojo::Server->new->load_app('./myapp.pl')->home;
184              
185             =head2 new
186              
187             my $server = Mojo::Server->new;
188             my $server = Mojo::Server->new(reverse_proxy => 1);
189             my $server = Mojo::Server->new({reverse_proxy => 1});
190              
191             Construct a new L object and subscribe to L event with default request handling.
192              
193             =head2 run
194              
195             $server->run;
196              
197             Run server. Meant to be overloaded in a subclass.
198              
199             =head1 SEE ALSO
200              
201             L, L, L.
202              
203             =cut