#!/usr/bin/perl use strict; use warnings; use Encode qw(decode_utf8); use HTML::Escape qw(escape_html); use Time::HiRes qw(gettimeofday tv_interval); use BSD::Resource; # 1. Start Benchmark Timer my $start_time = [gettimeofday]; my $search_text = ''; if ($ENV{QUERY_STRING} && $ENV{QUERY_STRING} =~ /^q=([^&]*)/) { $search_text = decode_utf8($1 // ""); $search_text =~ s/\P{Print}//g; $search_text = substr($search_text, 0, 64); $search_text =~ s/^\s+|\s+$//g; } my @results; my $files_read = 0; # Track IO Activity my $start_dir = '../log'; my @files = glob("$start_dir/*/index.html"); foreach my $path (@files) { next if -l $path || ! -f $path; # Using :encoding(UTF-8) to handle the valid text files next unless open(my $fh, "<:encoding(UTF-8)", $path); $files_read++; my $html = do { local $/; <$fh> }; close($fh); my ($text) = $html =~ m|
(.*?)
|is; $text =~ s|<[^>]+>| |g; $text =~ s|\s+| |g; next unless $text =~ /(.{0,40})(\Q$search_text\E)(.{0,40})/is; my ($before, $actual, $after) = ($1, $2, $3); $after =~ s/\s\S*$// if length($after) > 25; $before =~ s/^.*?\s// if length($before) > 25; if ($before =~ /\S/) { $before = ucfirst($before); } else { $before = ""; $actual = ucfirst($actual); } my $safe_before = escape_html($before); my $safe_actual = escape_html($actual); my $safe_after = escape_html($after); my $snippet = "${safe_before}${safe_actual}${safe_after}..."; my ($title) = $html =~ m|(.*?)|is; my $safe_title = escape_html($title || "No Title"); push @results, { path => $path, title => $safe_title, snippet => $snippet }; } # 2. Calculate Metrics my $end_time = [gettimeofday]; my $elapsed = tv_interval($start_time, $end_time); my $rusage = getrusage(); my $user_cpu = $rusage->utime; my $system_cpu = $rusage->stime; my $max_rss = $rusage->maxrss; # 3. Output print "Content-Type: text/html\n\n"; my $list; if ($search_text eq '') { $list = "

Please enter a search term above.

"; } elsif (@results == 0) { $list = "

No results found for \"$search_text\".

"; } else { $list = ""; } my $safe_search_text = escape_html($search_text); my $year = (localtime)[5] + 1900; print <<"HTML"; Search

Search

$list
Performance Metrics:
Total Time: @{[ sprintf("%.4f", $elapsed) ]} seconds
User CPU: $user_cpu s
System CPU: $system_cpu s
Peak RAM: $max_rss KB
Files Read: $files_read (IO Activity)
HTML