diff --git a/data/myapi.json b/data/myapi.json index a40a867..8478c30 100644 --- a/data/myapi.json +++ b/data/myapi.json @@ -5,5 +5,9 @@ "image_dl" : { "dir" : "/home/eleksr/img-save", "sleep" : 10 + }, + "upload" : { + "dir" : "/tmp/upload", + "auth": "iliveoncemore" } } diff --git a/lib/upload.pm b/lib/upload.pm new file mode 100644 index 0000000..f20d1a8 --- /dev/null +++ b/lib/upload.pm @@ -0,0 +1,53 @@ +package upload; + +our $VERSION = "1.0"; +use vars qw/$VERSION @EXPORT @ISA/; +require Exporter; +@EXPORT = qw (upload); +@ISA = "Exporter"; + +use strict; +use warnings "all"; +use diagnostics; +use Fcntl; +use conf; + +my $c = loadConf(); + +sub upload { + my $input = shift; + my $len = shift; + my $name = shift; + my ($status, $content, $msg) = ('400', 'text/plain', "Bad Request?\n"); + + if ($len > 0) { + if (sysopen (F, sprintf("%s/%s", $c->{upload}->{dir}, $name), O_CREAT|O_TRUNC|O_WRONLY)) { + my $buf; + my $readlen = 0; + my $totalread = 0; + my $buflen = 524288; # 512 kbytes, looks sane enough + + if ($len < $buflen) { + $buflen = $len; + } + + do { + $readlen = $input->read($buf, $buflen); + syswrite F, $buf, $readlen; + $totalread += $readlen; + } while ($readlen == $buflen); + + close F; + + if ($totalread != $len) { + ($status, $content, $msg) = ('400', $content, "Content-Length does not match amount of recieved bytes.\n"); + } else { + ($status, $content, $msg) = ('201', $content, "Uploaded.\n"); + } + } + } + + return ($status, $content, $msg); +} + +1; diff --git a/myapi.psgi b/myapi.psgi index da33e4b..63f4049 100644 --- a/myapi.psgi +++ b/myapi.psgi @@ -83,8 +83,22 @@ EOL ($status, $content, $msg) = me(); } elsif ($env->{PATH_INFO} eq "$prefix/image") { ($status, $content, $msg) = queue_image($env->{HTTP_LINK}, \@images); + } elsif ($env->{PATH_INFO} =~ /$prefix\/upload\/(.+)/) { + my $upload = $1; + ($status, $content, $msg) = ('400', $content, "Bad Request?\n"); + + if (defined($env->{HTTP_AUTH}) && ($env->{HTTP_AUTH} eq $CONF->{upload}->{auth})) { + if (($upload !~/(\.\.|\\|\/)/) && ($upload =~ /[A-Z|a-z|0-9|_|\-|\+]/)) { + if (defined($env->{CONTENT_LENGTH}) && ($env->{CONTENT_LENGTH} > 0)) { + ($status, $content, $msg) = upload($env->{'psgi.input'}, $env->{CONTENT_LENGTH}, $upload); + } + } + } else { + ($status, $content, $msg) = ('403', $content, "You're not allowed here. Fuck off.\n"); + } } + return [ $status, [ 'Content-Type' => $content, 'Content-Length' => length($msg) ],