From f88ff93ef92f3ce79cc01220c4ee9fcbc14649cb Mon Sep 17 00:00:00 2001 From: jake Date: Fri, 2 Sep 2022 19:36:44 -0400 Subject: Add 'Gone' gemini status --- TO_FIX.md | 2 ++ config.toml.sample | 12 +++++++ gmi.pl | 99 +++++++++++++++++++++++++++++++++++++++++------------- 3 files changed, 90 insertions(+), 23 deletions(-) diff --git a/TO_FIX.md b/TO_FIX.md index af0e0c1..0dd263e 100644 --- a/TO_FIX.md +++ b/TO_FIX.md @@ -23,3 +23,5 @@ handle signals like interrupt better recently-accepted-cert-cache for specific cert-req keys, doing a look up EACH and EVERY TIME can be expensive when it it likely that a single person will be looking around. reduce complexity in cert_req() + +put peer data in a global hash for easy access for logging and cgi scripts diff --git a/config.toml.sample b/config.toml.sample index a75fc25..6ec5e6a 100644 --- a/config.toml.sample +++ b/config.toml.sample @@ -136,3 +136,15 @@ assume_index = true # '../pubkeys2.txt', # ], #} +#gone = { +# # this checks if a path location doesn't exist, but does if '.gone' is appended, which will return a gone gemini status +# append = true, +# path = [ +# # regex matching +# '/some/path/that/is/percise/text.gmi', +# # This will match pretty a lot of things +# '/blog/2021*', +# # like '/blog/20215/april/' or even '/blog/2021-converense/' +# # in other words: be careful and be as specific as you can be! +# ] +#} diff --git a/gmi.pl b/gmi.pl index 246b809..269ed36 100755 --- a/gmi.pl +++ b/gmi.pl @@ -7,7 +7,7 @@ use warnings; use 5.010; #use diagnostics; -our $VERSION = 'v0.17.2'; +our $VERSION = 'v0.18.0'; # Modules use IO::Socket::SSL; # CPAN @@ -65,10 +65,10 @@ const our %GEM_RES_CODES => ( const our @VALID_DEFAULT_SETTINGS => qw/bind ports tls assume_index dir_listing root working_dir cert_key_dir log_file log_to_stdout default_mime cert_key_dir_write_warning fork timeout - unix redirection redirect/; + unix redirection redirect gone/; const our @VALID_VHOST_SETTINGS => qw/auto_cert assume_index dir_listing root cert key default_mime bind ports - unix redirection redirect cert_req/; + unix redirection redirect cert_req gone/; my ($config, $err) = from_toml(_slurp('./config.toml')); if ($err) { @@ -247,11 +247,20 @@ sub respond_to_client { } } + if (check_for_gone($vhost, $path)) { + goto DOC_GONE; + } + if (not $doc_loc = get_request_in_vhost_root($vhost, $path)) { - goto FAILURE; + goto FAILURE; } ### $doc_loc + # checking if the path already has .gone for 'some reason' + if (substr($doc_loc, -5, 5) eq '.gone') { ## no critic (MagicNumbers) + goto DOC_GONE; + } + # not a directory if (! -d $doc_loc) { goto DOC_ASSIGNED; @@ -291,6 +300,10 @@ sub respond_to_client { speak($cl, 'success', 'text/gemini', $doc_loc, $path); return; + DOC_GONE: + speak($cl, 'gone'); + return; + FAILURE: speak($cl, 'failure'); return; @@ -386,25 +399,7 @@ sub get_request_in_vhost_root { } } ### $r - - if (exists $config->{$vhost}{root}) { - my $p = accurate_path($config->{$vhost}{root}, $working_dir); - if (file_exists_and_readable("$p/$r")) { - return "$p/$r"; - } - } - # try default's root - elsif (exists $config->{default}{root}) { - my $p = accurate_path($config->{default}{root}, $working_dir); - if (file_exists_and_readable("$p/$r")) { - return "$p/$r"; - } - } - else { - serr("default and $vhost have improper root settings."); - return; - } - return; + return path_in_vhost_root_translated($vhost, $r); } sub file_exists_and_readable { @@ -1220,3 +1215,61 @@ sub cert_req { } return; } + +sub check_for_gone { + my ($vhost, $path) = @_; + $path ? ($path = "/$path") : ($path = '/'); + + if (exists $config->{$vhost}{gone}) { + if (exists $config->{$vhost}{gone}{append} and $config->{$vhost}{gone}{append} eq 'true') { + if (path_in_vhost_root_translated($vhost, "$path.gone")) { + return 1; + } + } + } + elsif (exists $config->{default}{gone}) { + if (exists $config->{default}{gone}{append} and $config->{default}{gone}{append} eq 'true') { + if (path_in_vhost_root_translated($vhost, "$path.gone")) { + return 1; + } + } + } + + ### check regex (default shouldn't have path) + if (exists $config->{$vhost}{gone}{path}) { + for my $gone (@{ $config->{$vhost}{gone}{path} }) { + ### $gone + my $gone_regex; + eval { + $gone_regex = qr{$gone}; + } or serr("$vhost: gone ($gone): $EVAL_ERROR") and return 0; + + if ($path =~ m/$gone_regex/) { + return 1; + } + } + } + return; +} + +sub path_in_vhost_root_translated { + my ($vhost, $request) = @_; + + if (exists $config->{$vhost}{root}) { + my $p = accurate_path($config->{$vhost}{root}, $working_dir); + if (file_exists_and_readable("$p/$request")) { + return "$p/$request"; + } + } + # try default's root + elsif (exists $config->{default}{root}) { + my $p = accurate_path($config->{default}{root}, $working_dir); + if (file_exists_and_readable("$p/$request")) { + return "$p/$request"; + } + } + else { + serr("default and $vhost have improper root settings."); + return; + } +} -- cgit v1.2.3