diff options
author | jake <jake@jakes-mail.top> | 2022-08-14 23:42:18 -0400 |
---|---|---|
committer | jake <jake@jakes-mail.top> | 2022-08-15 00:06:02 -0400 |
commit | 7473f06b1ffb4882849046cd258a8fdec1d2a181 (patch) | |
tree | 5de6c1f16a240e7dc5dfc521b0627c462e15e77d | |
parent | 398ee699343b94a1538d1c486330966707865878 (diff) |
Do not load entire request into memory.
Added support for webm magic detection.
Fix bug
Bug fix
-rw-r--r-- | .gitignore | 7 | ||||
-rw-r--r-- | TO_FIX.md | 11 | ||||
-rwxr-xr-x | gmi.pl | 69 |
3 files changed, 72 insertions, 15 deletions
@@ -10,3 +10,10 @@ example.com/ # make your own log file *.log + +# make your own systemd service file (for now) +*.service + +# not related to project +jakes_gemini_client/ +jakes_gemini_server/ diff --git a/TO_FIX.md b/TO_FIX.md new file mode 100644 index 0000000..e3a2b3e --- /dev/null +++ b/TO_FIX.md @@ -0,0 +1,11 @@ +TODO: +can log_file be written to? +add systemd unit? + +root_relative parameter is not needed, should be able to tell if a path is relative or not by the first character. +gmi.pl needs to accept an arguemnt, where the config.toml is located. + +default's root is relative to working_dir which is bad behavior. + +remove magic numbers +redirection bug where path = /share/dir, redirection says '30 share/dir/' resulting in '/share/share/dir/' @@ -7,7 +7,7 @@ use warnings; use 5.010; #use diagnostics; -our $VERSION = 'v0.0.2'; +our $VERSION = 'v0.0.3b'; # Modules use IO::Socket::SSL; # CPAN @@ -379,7 +379,7 @@ while () { my $cv = check_vhost_settings($vhost); # we already know it exists and is readable if (! -d $doc_loc) { - $doc = _slurp($doc_loc); + #$doc = _slurp($doc_loc); goto DOC_ASSIGNED; } elsif (-d $doc_loc) { @@ -392,13 +392,13 @@ while () { # if assume_index if (($cv == 1 or $cv == 3) and is_exists_and_readable($doc_loc. '/index.gmi') ) { $doc_loc .= '/index.gmi'; - $doc = _slurp($doc_loc); + #$doc = _slurp($doc_loc); goto DOC_ASSIGNED; } # if dir_listing elsif ($cv == 2 or $cv == 3) { - $doc = dir_listing($doc_loc, $path); - goto DOC_ASSIGNED; + #$doc = dir_listing($doc_loc, $path); + goto DIR_LISTING; } else { goto FAILURE; @@ -406,12 +406,28 @@ while () { } DOC_ASSIGNED: - my $meta = $ft->checktype_contents($doc); + #my $meta = $ft->checktype_contents($doc); + my $meta = $ft->checktype_filename($doc_loc); if ($meta eq "application/octet-stream") { # 'text/gemini' is non-standard mime-type if ((substr($doc_loc, -4, 4) eq '.gmi') or (substr($doc_loc, -1, 1) eq '/' and ($cv == 2 or $cv == 3))) { $meta = 'text/gemini'; } + # Manually support webm until better magic detection is used + elsif (substr($doc_loc, -4, 4) eq 'webm') { + open(my $fh, '<', $doc_loc); + my $h; + read($fh, $h, 1*1024); + if ($h =~ m/V_VP9/) { + $meta = 'video/VP9'; + } elsif ($h =~ m/V_VP8/) { + $meta = 'video/VP8'; + } else { + $meta = 'application/octet-stream'; + } + close $fh; + undef($h); + } elsif (exists $config->{$vhost}{default_mime}) { $meta = $config->{$vhost}{default_mime}; } @@ -420,11 +436,15 @@ while () { } ### $meta } - speak($cl, 'success', $meta, $doc); + speak($cl, 'success', $meta, $doc_loc); + goto CLOSE; + + DIR_LISTING: + speak($cl, 'success', 'text/gemini', $doc_loc, $path); goto CLOSE; FAILURE: - speak($cl, 'failure') or print $out "No file handle?"; + speak($cl, 'failure'); goto CLOSE; CLOSE: @@ -558,17 +578,36 @@ sub gem_code { return $res; } +# TODO: remove magic numbers sub speak { - my ($cl, $header, $meta, $doc) = @_; + my ($cl, $header, $meta, $doc_loc, $path) = @_; ### $meta my $head = gem_code($header, $meta); $log .= " $head"; - if ($doc) { - syswrite($cl, "$head\r\n"); - print $cl $doc; - } - else { - syswrite($cl, "$head\r\n"); + syswrite($cl, "$head\r\n"); + + if ($doc_loc) { + if (is_exists_and_readable($doc_loc) and ! -d $doc_loc) { + my $r; + open (my $fh, '<', $doc_loc); + # An SSL packet can only have about 16k bytes + # so, read less 16k, send it until eof + while (sysread($fh, $r, 15*1024)) { + syswrite($cl, $r); + undef($r); + } + close $fh; + } + elsif (is_exists_and_readable($doc_loc) and -d $doc_loc) { + my $doc; + $path ? ($doc = dir_listing($doc_loc, $path)) : ($doc = dir_listing($doc_loc)); + + # It is possible that a dir listing can produce more than 16k bytes + my $offset = 0; + while (my $w = syswrite($cl, $doc, 15*1024, $offset)) { + $offset += $w; + } + } } } |