File Coverage

blib/lib/Mojo/Server.pm
Criterion Covered Total %
statement 53 59 89.8
branch 11 18 61.1
condition 2 3 66.6
subroutine 13 14 92.8
pod 6 6 100.0
total 85 100 85.0


line stmt bran cond sub pod time code
1             package Mojo::Server;
2 53     53   370 use Mojo::Base 'Mojo::EventEmitter';
  53         116  
  53         371  
3              
4 53     53   359 use Carp qw(croak);
  53         142  
  53         2633  
5 53     53   786 use Mojo::File qw(path);
  53         165  
  53         2679  
6 53     53   1751 use Mojo::Loader qw(load_class);
  53         148  
  53         3134  
7 53     53   350 use Mojo::Util qw(md5_sum);
  53         127  
  53         2481  
8 53     53   9140 use POSIX ();
  53         105075  
  53         1375  
9 53     53   330 use Scalar::Util qw(blessed);
  53         129  
  53         52860  
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 119 my ($self, $app) = (shift, shift);
19 38         167 local $ENV{MOJO_EXE};
20 38 100       155 return $self->app($app->new(@_))->app unless my $e = load_class $app;
21 1 50       21 die ref $e ? $e : qq{Can't find application class "$app" in \@INC. (@INC)\n};
22             }
23              
24             sub build_tx {
25 953     953 1 1695 my $self = shift;
26 953         3082 my $tx = $self->app->build_tx;
27 953         1657 push @{$tx->req->trusted_proxies}, @{$self->trusted_proxies};
  953         2480  
  953         2922  
28 953 100       2936 $tx->req->reverse_proxy(1) if $self->reverse_proxy;
29 953         3244 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 17 100   17 1 87 my ($self, $path, @args) = (shift, shift, ref $_[0] ? %{shift()} : @_);
  1         5  
47              
48             # Clean environment (reset FindBin defensively)
49             {
50 17         33 local $0 = $path = path($path)->to_abs->to_string;
  17         58  
51 17         2203 require FindBin;
52 17         4351 FindBin->again;
53 17         3302 local @ENV{qw(MOJO_APP_LOADER MOJO_EXE)} = (1, undef);
54 17         65 local @ARGS_OVERRIDE = @args;
55              
56             # Try to load application from script into sandbox
57 17         52 delete $INC{$path};
58 17         34 my $app = eval "package Mojo::Server::Sandbox::@{[md5_sum $path]}; require \$path";
  17         1689  
59 17 100       223 die qq{Can't load application from file "$path": $@} if $@;
60 16 100 66     181 die qq{File "$path" did not return an application object.\n} unless blessed $app && $app->can('handler');
61 15         74 $self->app($app);
62             };
63 15         243 FindBin->again;
64              
65 15         2947 return $self->app;
66             }
67              
68             sub new {
69 233     233 1 21668 my $self = shift->SUPER::new(@_);
70 233     953   1843 $self->on(request => sub { shift->app->handler(shift) });
  953         2763  
71 233         1068 return $self;
72             }
73              
74 1     1 1 966 sub run { croak 'Method "run" not implemented by subclass' }
75              
76             1;
77              
78             =encoding utf8
79              
80             =head1 NAME
81              
82             Mojo::Server - HTTP/WebSocket server base class
83              
84             =head1 SYNOPSIS
85              
86             package Mojo::Server::MyServer;
87             use Mojo::Base 'Mojo::Server', -signatures;
88              
89             sub run ($self) {
90              
91             # Get a transaction
92             my $tx = $self->build_tx;
93              
94             # Emit "request" event
95             $self->emit(request => $tx);
96             }
97              
98             =head1 DESCRIPTION
99              
100             L is an abstract base class for HTTP/WebSocket servers and server interfaces, like L,
101             L, L, L, L and
102             L.
103              
104             =head1 EVENTS
105              
106             L inherits all events from L and can emit the following new ones.
107              
108             =head2 request
109              
110             $server->on(request => sub ($server, $tx) {...});
111              
112             Emitted when a request is ready and needs to be handled.
113              
114             $server->on(request => sub ($server, $tx) {
115             $tx->res->code(200);
116             $tx->res->headers->content_type('text/plain');
117             $tx->res->body('Hello World!');
118             $tx->resume;
119             });
120              
121             =head1 ATTRIBUTES
122              
123             L implements the following attributes.
124              
125             =head2 app
126              
127             my $app = $server->app;
128             $server = $server->app(MojoSubclass->new);
129              
130             Application this server handles, defaults to a L object.
131              
132             =head2 reverse_proxy
133              
134             my $bool = $server->reverse_proxy;
135             $server = $server->reverse_proxy($bool);
136              
137             This server operates behind a reverse proxy, defaults to the value of the C environment variable
138             or true if L is not empty.
139              
140             =head2 trusted_proxies
141              
142             my $proxies = $server->trusted_proxies;
143             $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']);
144              
145             This server expects requests from trusted reverse proxies, defaults to the value of the C
146             environment variable split on commas with optional whitespace. These proxies should be addresses or networks in CIDR
147             form.
148              
149             =head1 METHODS
150              
151             L inherits all methods from L and implements the following new ones.
152              
153             =head2 build_app
154              
155             my $app = $server->build_app('MyApp');
156             my $app = $server->build_app('MyApp', log => Mojo::Log->new);
157             my $app = $server->build_app('MyApp', {log => Mojo::Log->new});
158              
159             Build application from class and assign it to L.
160              
161             =head2 build_tx
162              
163             my $tx = $server->build_tx;
164              
165             Let application build a transaction.
166              
167             =head2 daemonize
168              
169             $server->daemonize;
170              
171             Daemonize server process.
172              
173             =head2 load_app
174              
175             my $app = $server->load_app('/home/sri/myapp.pl');
176             my $app = $server->load_app('/home/sri/myapp.pl', log => Mojo::Log->new);
177             my $app = $server->load_app('/home/sri/myapp.pl', {log => Mojo::Log->new});
178              
179             Load application from script and assign it to L.
180              
181             say Mojo::Server->new->load_app('./myapp.pl')->home;
182              
183             =head2 new
184              
185             my $server = Mojo::Server->new;
186             my $server = Mojo::Server->new(reverse_proxy => 1);
187             my $server = Mojo::Server->new({reverse_proxy => 1});
188              
189             Construct a new L object and subscribe to L event with default request handling.
190              
191             =head2 run
192              
193             $server->run;
194              
195             Run server. Meant to be overloaded in a subclass.
196              
197             =head1 SEE ALSO
198              
199             L, L, L.
200              
201             =cut