diff --git a/miniserv.pl b/miniserv.pl index 8f25d1c06..93164d8f5 100755 --- a/miniserv.pl +++ b/miniserv.pl @@ -2128,9 +2128,9 @@ if ($config{'userfile'}) { &write_data("\r\n"); &reset_byte_count(); &write_data("\n"); - &write_data("401 — Unauthorized\n"); - &write_data("

401 — Unauthorized

\n"); - &write_data("

A password is required to access this\n"); + &write_data("".&embed_error_styles($roots[0])."401 — Unauthorized\n"); + &write_data("

401 — Unauthorized

\n"); + &write_data("

A password is required to access this\n"); &write_data("web server. Please try again.

\n"); &write_data("\n"); &log_request($loghost, undef, $reqline, 401, &byte_count()); @@ -2389,8 +2389,8 @@ if (-d _) { &write_keep_alive(0); &write_data("\r\n"); &reset_byte_count(); - &write_data("

Index of $simple

\n"); - &write_data("
\n");
+	&write_data("".&embed_error_styles($roots[0])."

Index of $simple

\n"); + &write_data("
\n");
 	&write_data(sprintf "%-35.35s %-20.20s %-10.10s\n",
 			"Name", "Last Modified", "Size");
 	&write_data("
\n"); @@ -2810,10 +2810,10 @@ else { &write_data("\r\n"); &reset_byte_count(); &write_data("\n"); - &write_data("$code — $msg\n"); - &write_data("

Error — $msg

\n"); + &write_data("".&embed_error_styles($roots[0])."$code — $msg\n"); + &write_data("

Error — $msg

\n"); if ($body) { - &write_data("

$body

\n"); + &write_data("

$body

\n"); } &write_data("\n"); } @@ -2824,6 +2824,23 @@ shutdown(SOCK, 1); exit if (!$noexit); } +# embed_error_styles() +# Returns HTML styles for nicer errors. For internal use only. +sub embed_error_styles +{ +my ($root) = @_; +if ($root) { + my $err_style = &read_any_file("$root/unauthenticated/errors.css"); + if ($err_style) { + $err_style =~ s/[\n\r]//g; + $err_style =~ s/\s+/ /g; + $err_style = ""; + return "\n$err_style\n"; + } + } +return undef; +} + sub get_type { if ($_[0] =~ /\.([A-z0-9]+)$/) { @@ -3137,7 +3154,7 @@ local($idx, $more, $rv); while(($idx = index($main::read_buffer, "\n")) < 0) { if (length($main::read_buffer) > 100000 && !$nolimit) { &http_error(414, "Request too long", - "Received excessive line
".&html_strip($main::read_buffer)."
"); + "Received excessive line
".&html_strip($main::read_buffer)."
"); } # need to read more.. @@ -4681,6 +4698,19 @@ close(CONF); return %rv; } +# read_any_file(file) +# Reads any given file and returns its content +sub read_any_file +{ +my ($realfile) = @_; +my $rv; +open(my $fh, "<".$realfile) || return $rv; +local $/; +$rv = <$fh>; +close($fh); +return $rv; +} + # update_vital_config() # Updates %config with defaults, and dies if something vital is missing sub update_vital_config @@ -6472,22 +6502,3 @@ sub getenv my ($key) = @_; return $ENV{ uc($key) } || $ENV{ lc($key) }; } - -# get_error_style(style_for) -# Returns a style for error messages -sub get_error_style -{ -my ($type, $extra_style) = @_; -my $style = ' style="font-family:Lucida Console,Courier,monospace;'; -if ($type eq 'heading') { - $style .= 'color:#f12b2b;font-size:14px;padding:5px 2.5px 0;transform:scale(1,1.5);text-transform:uppercase;white-space:pre-wrap;font-weight:500;'; - } -if ($type eq 'content') { - $style .= 'font-size:12.5px;padding-left:2.5px;white-space:pre-wrap;'; - } -if ($type eq 'body') { - $style .= 'font-size:12.5px;'; - } -$style .= "$extra_style\""; -return $style; -} diff --git a/unauthenticated/errors.css b/unauthenticated/errors.css new file mode 100644 index 000000000..9b7183f5b --- /dev/null +++ b/unauthenticated/errors.css @@ -0,0 +1,83 @@ +.err-head, +.err-content, +.err-body { + font-family: Lucida Console, Courier, monospace; +} + +.err-head { + color: #f12b2b; + font-size: 14px; + font-weight: 500; + padding: 5px 2.5px 0; + text-transform: uppercase; + transform: scale(1, 1.5); + white-space: pre-wrap; +} + +.err-content { + padding-left: 2.5px; + white-space: pre-wrap; +} + +.err-content, +.err-body { + font-size: 12.5px; +} + +.err-head[data-fatal-error-text] { + padding: 0; +} + +.err-stack caption, +.err-stack > tbody > tr:first-child > td > b { + color: #151515; + font-weight: bold; + text-align: left; +} + +.err-stack > tbody > tr:first-child > td > b { + border-bottom: 1px solid #151515; +} + +.err-stack > tbody > tr:first-child>td { + font-family: unset; + font-size: 14px; + height: 25px; + text-transform: uppercase; + transform: scale(1, 1.2); + vertical-align: top; +} + +.err-stack { + border: 1px dashed #151515 +} + +.err-stack.captured { + margin-left: 12px; + width: auto +} +.err-stack tr td { + font-family: Lucida Console, Courier, monospace; + font-size: 13px; + padding: 1px 10px; + transform: scale(1, 1.15); +} + +.err-stack tr:not(:first-child) td.captured { + font-size: 90%; +} + +.err-stack > tr:first-child > td.captured { + font-size: 96%; + padding-bottom: 7px; + padding-top: 3px; +} + +.err-stack caption.err-head { + padding:0 0 10px 0; +} + +.err-stack caption.err-head.captured { + color: #222; + font-size:98%; +} diff --git a/web-lib-funcs.pl b/web-lib-funcs.pl index a13e003f9..38ce57f4f 100755 --- a/web-lib-funcs.pl +++ b/web-lib-funcs.pl @@ -1659,9 +1659,16 @@ elsif ($ENV{'REQUEST_URI'} =~ /json-error=1/) { } else { &header($text{'error'}, ""); - my $hh = $miniserv::page_capture; + my $hh = $miniserv::page_capture ? " captured" : ""; + my $err_style = &read_file_contents("$root_directory/unauthenticated/errors.css"); + if ($err_style) { + $err_style =~ s/[\n\r]//g; + $err_style =~ s/\s+/ /g; + $err_style = ""; + print "\n$err_style\n"; + } print "
\n" if ($hh); - if ($hh) { + if ($hh) { print "

",($main::whatfailed ? "$main::whatfailed : " : ""), @_,"

\n"; } @@ -1673,32 +1680,22 @@ else { $error_text = " — $error_html"; $error_html = undef; } - print "$text{'error'}

$text{'error'}$error_text

$error_html
\n"; + print "$text{'error'}

$text{'error'}$error_text

$error_html
\n"; } if ($gconfig{'error_stack'}) { # Show call stack - print "\n"; - my $caption_no_header_style = - &miniserv::get_error_style('heading', "padding:0 0 10px 0;" . ($hh ? "color: #222;font-size:98%;" : "") . ""); + my $cls_err_caption = " class=\"err-head$hh\""; + my $cls_err_td = $hh ? " class=\"@{[&trim($hh)]}\"" : ""; print "
\n" if ($hh); - print "$text{'error_stack'}\n"; - print " ", - " ", - "\n"; + print "
$text{'error_file'}$text{'error_line'}$text{'error_sub'}
$text{'error_stack'}\n"; + print "$text{'error_file'} ", + "$text{'error_line'} ", + "$text{'error_sub'} \n"; for($i=0; my @stack = caller($i); $i++) { print "\n"; - print "\n"; - print "\n"; - print "\n"; + print "$stack[1]\n"; + print "$stack[2]\n"; + print "$stack[3]\n"; print "\n"; } print "
$stack[1]$stack[2]$stack[3]
\n"; @@ -3854,7 +3851,7 @@ else { delete($ENV{'FOREIGN_ROOT_DIRECTORY'}); } @INC = @OLDINC; -if ($@) { &error("
Require $mod/$files[0] failed : $@
"); } +if ($@) { &error("
Require $mod/$files[0] failed : $@
"); } return 1; } @@ -11040,7 +11037,7 @@ foreach my $e (@_) { return @rv; } -=head2 list_combined_webmin_menu(&data, &in) +=head2 list_combined_webmin_menu(&data, &in, [$mod]) Returns an array of objects, each representing a menu item that a theme should render such as on a left menu. Each object is a hash ref with the following @@ -11084,16 +11081,18 @@ possible keys : The &data parameter is a hash ref of additional information that the theme supplies to all modules. The &in param is the CGI inputs from the menu, for -use where the menu has a form that submits to itself. +use where the menu has a form that submits to itself, and [$mod] param binds +a function return to a given module call =cut sub list_combined_webmin_menu { -my ($data, $in) = @_; +my ($data, $in, $mod) = @_; foreach my $m (&get_available_module_infos()) { my $dir = &module_root_directory($m->{'dir'}); my $mfile = "$dir/webmin_menu.pl"; next if (!-r $mfile); + next if (defined($mod) && $mod ne $m->{'dir'}); eval { local $main::error_must_die = 1; &foreign_require($m->{'dir'}, "webmin_menu.pl");