summaryrefslogtreecommitdiff
path: root/gmi.pl
blob: 36a9cd175cadc500b2fc50691e9058c7115e29aa (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#!/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();