File Coverage

blib/lib/WWW/Suffit/Plugin/ServerInfo.pm
Criterion Covered Total %
statement 15 144 10.4
branch 0 50 0.0
condition 0 20 0.0
subroutine 5 9 55.5
pod 1 1 100.0
total 21 224 9.3


line stmt bran cond sub pod time code
1             package WWW::Suffit::Plugin::ServerInfo;
2 1     1   148773 use strict;
  1         7  
  1         43  
3 1     1   7 use warnings;
  1         3  
  1         78  
4 1     1   707 use utf8;
  1         312  
  1         8  
5              
6             =encoding utf8
7              
8             =head1 NAME
9              
10             WWW::Suffit::Plugin::ServerInfo - The WWW::Suffit Plugin for show Server and Perl environment data
11              
12             =head1 SYNOPSIS
13              
14             # in your startup
15             $self->plugin('WWW::Suffit::Plugin::ServerInfo', {
16             route => "/serverinfo",
17             });
18              
19             ...or:
20              
21             # in your startup
22             $self->plugin('WWW::Suffit::Plugin::ServerInfo');
23             $self->routes->get('/serverinfo1')->to('ServerInfo#info');
24             $self->routes->get('/serverinfo2' => sub { shift->serverinfo });
25              
26             # Curl Examples:
27             curl -H "Accept: text/html" http://localhost:8080/serverinfo
28             curl -H "Accept: text/plain" http://localhost:8080/serverinfo
29             curl -H "Accept: application/json" http://localhost:8080/serverinfo
30              
31             =head1 DESCRIPTION
32              
33             The WWW::Suffit Plugin for show Server and Perl environment data
34              
35             =head1 OPTIONS
36              
37             This plugin supports the following options
38              
39             =head2 debug
40              
41             debug => 1,
42              
43             Switches on the debug mode. This mode performs show log history and dump of config
44              
45             =head2 route
46              
47             route => "/serverinfo",
48              
49             Sets route name and show server info by it
50              
51             =head2 template
52              
53             template => "suffit_serverinfo",
54              
55             Sets template for rendering. Default: suffit_serverinfo
56              
57             =head1 METHODS
58              
59             Internal methods
60              
61             =head2 register
62              
63             Do not use directly. It is called by Mojolicious.
64              
65             =head1 SEE ALSO
66              
67             L, L
68              
69             =head1 AUTHOR
70              
71             Serż Minus (Sergey Lepenkov) L Eabalama@cpan.orgE
72              
73             =head1 COPYRIGHT
74              
75             Copyright (C) 1998-2026 D&D Corporation
76              
77             =head1 LICENSE
78              
79             This program is distributed under the terms of the Artistic License Version 2.0
80              
81             See the C file or L for details
82              
83             =cut
84              
85 1     1   900 use Mojo::Base 'Mojolicious::Plugin';
  1         13805  
  1         6  
86              
87             our $VERSION = '1.02';
88              
89 1     1   2302 use Mojo::File qw/ path /;
  1         259601  
  1         2260  
90              
91             sub register {
92 0     0 1   my ($plugin, $app, $opts) = @_; # $self = $plugin
93 0   0       $opts //= {};
94              
95             # Add classes
96 0           push @{$app->renderer->classes}, __PACKAGE__;
  0            
97 0           push @{$app->static->classes}, __PACKAGE__;
  0            
98 0           my $ns = 0;
99 0 0         for (@{$app->routes->namespaces}) { $ns = 1 if $_ eq 'WWW::Suffit::Server' }
  0            
  0            
100 0 0         push @{$app->routes->namespaces}, 'WWW::Suffit::Server' unless $ns;
  0            
101              
102             # Helpers
103 0           $app->helper('serverinfo', => \&_serverinfo);
104              
105             # Set template
106 0   0       my $template = $opts->{template} || 'suffit_serverinfo';
107 0           $app->{'__suffit_serverinfo_template'} = $template;
108              
109             # Set debug mode
110 0 0         $app->{'__suffit_serverinfo_debug'} = $opts->{debug} ? 1 : 0;
111              
112             # Set ANY route to root:
113 0 0 0       if (my $route_name = $opts->{routename} || $opts->{route}) { # '/serverinfo'
114             #$app->routes->any($route_name => {template => $template} => sub { shift->render } );
115             #$app->routes->any($route_name)->to('ServerInfo#info');
116 0     0     $app->routes->any($route_name => sub { shift->serverinfo });
  0            
117             }
118             }
119             sub _serverinfo {
120 0     0     my $self = shift;
121 0           my @o = ();
122              
123             # Filtered stash snapshot
124 0           my $stash = $self->stash;
125 0           my $snapshot;
126 0 0         %{$snapshot = {}} = map { $_ => $_ eq 'app' ? 'DUMMY' : $stash->{$_} } grep { !/^mojo\./ and defined $stash->{$_} } keys %$stash;
  0 0          
  0            
  0            
127              
128 0           my $url = $self->req->url;
129 0   0       my $params = $self->req->params->to_hash || {};
130             my $s = sub {
131 0     0     my $sec = shift; # sec - gen, ext, dat
132 0           my $typ = shift; # typ - str, txt, obj, dmp
133 0           my $key = shift; # key - Key
134 0           my $val = shift; # val - Value
135 0           push @o, {
136             sec => $sec,
137             typ => $typ,
138             key => $key,
139             val => $val,
140             };
141 0           };
142              
143             # General
144 0           push @o, "-"x80 . " gen " . "---";
145 0           $s->("gen", "str", 'Request ID' => $self->req->request_id);
146 0           $s->("gen", "str", 'Method' => $self->req->method);
147 0           $s->("gen", "str", 'Base URL' => $url->base->to_string);
148 0           $s->("gen", "str", 'URL' => $url->to_string);
149 0           $s->("gen", "str", 'Router name'=> $self->match->endpoint->name);
150 0           $s->("gen", "str", 'HTTP Version' => $self->req->version);
151 0 0         $s->("gen", "str", 'Remote IP' => $self->can('remote_ip') ? $self->remote_ip : $self->tx->remote_address);
152             { # Headers
153 0           my @obj;
154 0           foreach my $n (sort @{$self->req->headers->names}) {
  0            
155 0           push @obj, [$n, $self->req->headers->header($n)];
156             }
157 0           $s->("gen", "obj", 'Request headers', [@obj]);
158             }
159             { # Parameters
160 0           my @obj;
  0            
  0            
161 0           foreach my $n (sort keys %$params) {
162 0   0       push @obj, [$n, $params->{$n} // ''];
163             }
164 0           $s->("gen", "obj", 'Request parameters', [@obj]);
165             }
166 0           $s->("gen", "dmp", 'Stash' => $snapshot);
167 0           $s->("gen", "dmp", 'Session' => $self->session);
168              
169             # Extends
170 0           push @o, "-"x80 . " ext " . "---";
171 0           $s->("ext", "str", 'Perl' => "$^V ($^O)");
172 0           $s->("ext", "str", 'Mojolicious' => sprintf("%s (%s)", $Mojolicious::VERSION, $Mojolicious::CODENAME));
173 0           $s->("ext", "str", 'Moniker' => $self->app->moniker);
174 0           $s->("ext", "str", 'Name' => $0);
175 0           $s->("ext", "str", 'Executable' => $^X);
176 0           $s->("ext", "str", 'PID' => $$);
177 0           $s->("ext", "str", 'Time' => scalar localtime(time));
178 0           $s->("ext", "str", 'Home' => $self->app->home->to_string);
179 0 0         $s->("ext", "str", 'Document root' => $self->app->documentroot) if $self->app->can('documentroot');
180 0 0         $s->("ext", "str", 'Data dir' => $self->app->datadir) if $self->app->can('datadir');
181 0           $s->("ext", "dmp", 'Template paths' => $self->app->renderer->paths);
182 0           $s->("ext", "dmp", 'Template classes'=>$self->app->renderer->classes);
183 0           $s->("ext", "dmp", 'Static paths' => $self->app->static->paths);
184 0           $s->("ext", "dmp", 'Namespaces' => $self->app->routes->namespaces);
185 0           $s->("ext", "dmp", 'Include' => \@INC);
186 0 0         $s->("ext", "dmp", 'Config' => $self->app->config) if $self->app->{'__suffit_serverinfo_debug'};
187              
188             { # Environment variables
189 0           my @obj;
190 0           foreach my $k (sort keys %ENV) {
191 0   0       push @obj, [$k, $ENV{$k} // ''];
192             }
193 0           $s->("gen", "obj", 'Environment variables', [@obj]);
194             }
195              
196             { # %INC
197 0           my @obj;
  0            
  0            
198 0           foreach my $k (sort keys %INC) {
199 0           my $module = $k;
200 0 0         if ($k =~ /.pm$/) {
201 0           $module =~ s{\/}{::}gsmx;
202 0           $module =~ s/.pm$//g;
203             } else {
204 0           $module = path($k)->basename;
205             }
206 0   0       push @obj, [$module, $INC{$k} // ''];
207             }
208 0           $s->("gen", "obj", 'Loaded modules', [@obj]);
209             }
210              
211             # Data
212 0   0       my $raw_data = $self->req->body // '';
213 0 0         if (length($raw_data)) {
214 0           push @o, "-"x80 . " dat " . "---";
215 0           $s->("ext", "txt", 'Request data' => $raw_data);
216             }
217              
218             # Text output
219 0           my @text = ();
220 0           foreach my $r (@o) {
221 0 0         unless (ref($r) eq 'HASH') {
222 0           push @text, $r, "\n";
223 0           next;
224             }
225 0           my $typ = $r->{typ}; # typ - str, txt, obj
226 0           my $key = $r->{key}; # key - Key
227 0           my $val = $r->{val}; # val - Value
228 0 0 0       if ($typ eq 'str') {
    0          
    0          
    0          
229 0           push @text, sprintf("%-*s: %s\n", 24, $key, $val);
230             } elsif ($typ eq 'txt') {
231 0           push @text, sprintf("%s:\n%s", $key, $val);
232             } elsif ($typ eq 'dmp') {
233 0           push @text, sprintf("%s: %s", $key, $self->dumper($val));
234             } elsif ($typ eq 'obj' and ref($val) eq 'ARRAY') {
235 0           push @text, sprintf("%s:\n", $key);
236 0           foreach my $p (@$val) {
237 0           push @text, sprintf(" %-*s: %s\n", 22, @$p);
238             }
239             }
240             }
241              
242             # Json
243 0           my %json = ();
244 0           foreach my $r (@o) {
245 0 0         next unless ref($r) eq 'HASH';
246 0           my $key = $r->{key}; # key - Key
247 0           my $val = $r->{val}; # val - Value
248 0           $json{$key} = $val;
249             }
250              
251             # HTML
252 0           my (@html, @headers, @parameters, @environments, @modules) = ();
253 0           foreach my $r (@o) {
254 0 0         next unless ref($r) eq 'HASH';
255 0 0         if ($r->{typ} eq 'obj') {
256 0 0         if ($r->{key} eq 'Request headers') {
    0          
    0          
    0          
257 0           @headers = @{$r->{val}};
  0            
258             } elsif ($r->{key} eq 'Request parameters') {
259 0           @parameters = @{$r->{val}};
  0            
260             } elsif ($r->{key} eq 'Environment variables') {
261 0           @environments = @{$r->{val}};
  0            
262             } elsif ($r->{key} eq 'Loaded modules') {
263 0           @modules = @{$r->{val}};
  0            
264             }
265             } else {
266 0 0         next if $r->{key} eq 'Include';
267 0           push @html, $r;
268             }
269             }
270              
271             # Render
272             return $self->respond_to(
273             json => {
274             json => \%json,
275             },
276             text => {
277             text => join("", @text),
278             },
279             html => {
280 0           template => $self->app->{'__suffit_serverinfo_template'},
281             general => \@html,
282             headers => \@headers,
283             parameters => \@parameters,
284             environments => \@environments,
285             atinc => \@INC,
286             modules => \@modules,
287             },
288             any => {
289             text => join("", @text),
290             },
291             );
292             #return $self->render(template => $self->app->{'__suffit_serverinfo_template'});
293             }
294              
295             1;
296              
297             __DATA__