Last active
June 22, 2020 16:43
-
-
Save wwalker/c73051f1b22a60c9643a6d22e785b976 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
# A simple web server that just listens for textarea filter requests | |
# and runs an editor to manipulate the text. Is intended to be | |
# used with the TextAid extention for Chrome. | |
use strict; | |
use warnings; | |
use threads; | |
use Socket; | |
use IO::Select; | |
use File::Temp; | |
our $PORT = 9292; | |
our $EDITOR_CMD = "$ENV{HOME}/bin/xvim '%s'"; | |
#our $EDITOR_CMD = '/usr/bin/emacsclient -c "%s"'; | |
our $TMPDIR = '/tmp'; | |
our $CLEAN_AFTER_HOURS = 4; | |
$| = 1; | |
local *S; | |
socket(S, PF_INET, SOCK_STREAM , getprotobyname('tcp')) or die "couldn't open socket: $!\n"; | |
setsockopt(S, SOL_SOCKET, SO_REUSEADDR, 1); | |
bind(S, sockaddr_in($PORT, inet_aton("127.0.0.1"))); | |
listen(S, 5) or die "listen failed: $!\n"; | |
my $sel = IO::Select->new(); | |
$sel->add(*S); | |
while (1) { | |
my @con = $sel->can_read(); | |
foreach my $con (@con) { | |
my $fh; | |
my $remote = accept($fh, $con); | |
my($port, $iaddr) = sockaddr_in($remote); | |
my $addr = inet_ntoa($iaddr); | |
my $t = threads->create(\&do_edit, $fh); | |
$t->detach(); | |
} | |
} | |
exit; | |
# Read the text from the content body, edit it, and write it back as our output. | |
sub do_edit | |
{ | |
my($fh) = @_; | |
binmode $fh; | |
local $_ = <$fh>; | |
my($method, $path, $ver) = /^(GET|HEAD|POST)\s+(.*?)\s+(HTTP\S+)/; | |
unless (defined $ver) { | |
http_header($fh, 500, 'Invalid request.'); | |
close $fh; | |
return; | |
} | |
if ($method ne 'POST') { | |
http_header($fh, 200, 'Server is up and running. To use it, issue a POST request with the file to edit as the content body.'); | |
close $fh; | |
return; | |
} | |
my %header; | |
while (<$fh>) { | |
s/\r?\n$//; | |
last if $_ eq ''; | |
my($name, $value) = /^(.*?): +(.*)/; | |
$header{lc($name)} = $value; | |
} | |
my $len = $header{'content-length'}; | |
unless (defined $len && $len =~ /^\d+$/) { | |
http_header($fh, 500, 'Invalid request -- no content-length.'); | |
close $fh; | |
return; | |
} | |
my $tmp = new File::Temp( | |
TEMPLATE => 'edit-server-XXXXXX', | |
DIR => $TMPDIR, | |
SUFFIX => '.txt', | |
UNLINK => 0, | |
); | |
my $name = $tmp->filename; | |
my $got = read($fh, $_, $len); | |
if ($got != $len) { | |
http_header($fh, 500, 'Invalid request -- wrong content-length.'); | |
close $fh; | |
return; | |
} | |
print $tmp $_; | |
close $tmp; | |
my $cmd = sprintf($EDITOR_CMD, $name); | |
system $cmd; | |
unless (open FILE, '<', $name) { | |
http_header($fh, 500, "Unable to re-open $name: $!"); | |
close $fh; | |
return; | |
} | |
http_header($fh, 200); | |
print $fh <FILE>; | |
close FILE; | |
close $fh; | |
# Clean-up old tmp files that have been around for a few hours. | |
if (opendir(DP, $TMPDIR)) { | |
foreach my $fn (grep /^edit-server-......\.txt$/, readdir DP) { | |
$fn = "$TMPDIR/$fn"; | |
if (-M $fn > $CLEAN_AFTER_HOURS/24) { | |
unlink $fn; | |
} | |
} | |
closedir DP; | |
} | |
} | |
sub http_header | |
{ | |
my $fh = shift; | |
my $status = shift; | |
print $fh "HTTP/1.0 $status\r\n", | |
"Server: edit-server\r\n", | |
"Content-Type: text/plain\r\n", | |
"\r\n", @_; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
xterm -e vim "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment