#!/usr/bin/perl # this is a gemini server use strict; use warnings; #use diagnostics; our $VERSION = 'v0.0.1'; # Modules use IO::Socket::SSL; # CPAN use URL::XS qw(parse_url split_url_path parse_url_query); # CPAN #use Term::ANSIColor; # Core #use Path::Naive qw(normalize_path); # CPAN use Smart::Comments; # CPAN #use URI::Encode qw(uri_encode); # CPAN use IO::Select; # sudo cpanm IO::Socket::SSL URL::XS Text::Wraper Path::Naive Term::ReadLine Smart::Comments URI::Encode my $srv = IO::Socket::SSL->new( #SSL_server => 1, LocalAddr => '0.0.0.0', LocalPort => 1965, Listen => 10, SSL_cert_file => './cert.pem', SSL_key_file => './key.pem', SSL_fast_shutdown => 1, ) or die "error=$!, ssl_error=$SSL_ERROR"; while (1) { my $cl = $srv->accept(); sysread($cl,my $data,1024); my $clhost = $cl->peerhost(); my $clport = $cl->peerport(); print "Connection from $clhost:$clport - $data"; my $url; my $path; substr($data,-2,2,''); # removing \r\n eval { $url = parse_url($data); }; $path = $url->{path}; my $doc; ### $data ### $url ### $path if ($path) { # Note: this will serve ANYTHING including /etc/passwd and other sensitive files open (my $FH ,'<', "./$path") or syswrite($cl,"51 Not Found\r\n") and $cl->close('SHUT_WR') and next; while (<$FH>) { $doc .= $_; } close ($FH); syswrite($cl,"20 text/gemini\r\n$doc",0); } else { syswrite($cl,"50 Failure\r\n"); $cl->close('SHUT_WR'); } $cl->close('SHUT_WR'); } $srv->close();