Skip to content

Instantly share code, notes, and snippets.

@feklee
Last active January 10, 2025 16:42
Show Gist options
  • Save feklee/c3945a920aaa6c0dfeea47d1df1da5e1 to your computer and use it in GitHub Desktop.
Save feklee/c3945a920aaa6c0dfeea47d1df1da5e1 to your computer and use it in GitHub Desktop.
Webserver that redirects URLs of my documents to URLs where they can be viewed
#!/usr/bin/perl
# Web server that redirects from docurls to a URLs where the
# associated files can be found, e.g.:
#
# /a04 -> http://filebrowser.f76.eu/files/my_data/Internet/standards/README
# Felix E. Klee <[email protected]>
use strict;
use warnings;
use HTML::Entities;
my $cache_filename = glob "~/.local/share/docurl_cache";
my $base_url = "http://filebrowser.f76.eu/files/my_data/";
my %paths;
my $toc_rows;
sub add_toc_row {
my ($id, $path) = @_;
$path = encode_entities($path);
$toc_rows .= <<"EOF"
<tr><td><a href="/$id">$id</a></td><td>$path</td></tr>
EOF
}
sub toc {
my $message = <<"EOF";
<!DOCTYPE html>
<html lang="en">
<title>TOC</title>
<meta charset="utf-8">
<table>
<thead>
<tr>
<th>ID</th>
<th>Path</th>
</tr>
</thead>
<tbody>
$toc_rows
</tbody>
</table>
</html>
EOF
}
# The cache file describes the mapping between the IDs in docurls and
# the file paths.
sub read_cache {
%paths = ();
open CACHE, '<', $cache_filename or die $!;
$toc_rows = '';
while (<CACHE>) {
chomp $_;
next if /^#/;
next if /^$/;
my ($id, $path) = split(/\s+/, $_, 2);
if (defined $id && defined $path) {
$paths{$id} = $path;
add_toc_row($id, $path);
}
}
}
my $app = sub {
my $env = shift;
my $id = $env->{PATH_INFO};
$id =~ s{^/}{}; # Remove leading slash
read_cache();
if ($id eq "") {
return [
200,
['Content-Type' => 'text/html; charset=UTF-8'],
[toc()]];
} elsif (exists $paths{$id}) {
return [
302,
['Location' => $base_url.$paths{$id}],
[]];
} else {
return [
404,
['Content-Type' => 'text/plain'],
["Not found\n"]];
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment