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   436 use Mojo::Base 'Mojo::EventEmitter';
  57         112  
  57         385  
3              
4 57     57   478 use Carp qw(croak);
  57         106  
  57         3513  
5 57     57   1113 use Mojo::File qw(path);
  57         350  
  57         2883  
6 57     57   1878 use Mojo::Loader qw(load_class);
  57         135  
  57         3345  
7 57     57   381 use Mojo::Util qw(md5_sum);
  57         123  
  57         2718  
8 57     57   10072 use POSIX ();
  57         134378  
  57         1638  
9 57     57   288 use Scalar::Util qw(blessed);
  57         378  
  57         69325  
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 127 my ($self, $app) = (shift, shift);
19 38         214 local $ENV{MOJO_EXE};
20 38 100       226 return $self->app($app->new(@_))->app unless my $e = load_class $app;
21 1 50       37 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 2066 my $self = shift;
26 1031         4460 my $tx = $self->app->build_tx;
27 1031         2108 push @{$tx->req->trusted_proxies}, @{$self->trusted_proxies};
  1031         3742  
  1031         3914  
28 1031 100       4196 $tx->req->reverse_proxy(1) if $self->reverse_proxy;
29 1031         4444 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 168 my ($self, $path, @args) = (shift, shift, ref $_[0] ? %{shift()} : @_);
  1         4  
47              
48             # Clean environment (reset FindBin defensively)
49             {
50 18         38 local $0 = $path = path($path)->to_abs->to_string;
  18         90  
51 18         3151 require FindBin;
52 18         6693 FindBin->again;
53 18         4684 local @ENV{qw(MOJO_APP_LOADER MOJO_EXE)} = (1, undef);
54 18         75 local @ARGS_OVERRIDE = @args;
55              
56             # Try to load application from script into sandbox
57 18         10407 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       447 die qq{Can't load application from file "$path": $@} if $@;
62 17 100 66     266 die qq{File "$path" did not return an application object.\n} unless blessed $app && $app->can('handler');
63 16         93 $self->app($app);
64             };
65 16         144 FindBin->again;
66              
67 16         3610 return $self->app;
68             }
69              
70             sub new {
71 266     266 1 71044 my $self = shift->SUPER::new(@_);
72 266     1031   2647 $self->on(request => sub { shift->app->handler(shift) });
  1031         3548  
73 266         1282 return $self;
74             }
75              
76 1     1 1 1924 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