use Cro::HTTP::Server;
use Cro::HTTP::Router;
use Cro::HTTP::Log::File;
unit sub MAIN(
Bool :$debug = True, #= enable debug mode
);
my IO() $store = "store";
mkdir $store;
die "Store doesn't exist" unless $store.d;
my $application = route {
post -> 'create' {
request-body -> (:$name) {
my Str $id = ('a'...'z', 'A'...'Z', 0...9).roll(32).join;
my Str $auth = ('a'...'z', 'A'...'Z', 0...9).roll(32).join;
my IO() $user-store = "%s/%s".sprintf: $store, $id;
mkdir $user-store;
mkdir "$user-store/images";
die "Failed to create user store" unless $user-store.d;
spurt "$user-store/name", "$name";
spurt "$user-store/auth", "$auth";
content 'application/json', %(:$id, :$auth);
}
}
post -> 'verify' {
request-body -> (:$id, :$auth) {
my IO() $user-store = "%s/%s".sprintf: $store, $id;
my %res;
if $user-store.d {
if "$user-store/auth".IO.slurp ne $auth {
response.status = 401;
} else {
%res<name> = "$user-store/name".IO.slurp;
}
} else {
response.status = 404;
}
content 'application/json', %res;
}
}
post -> 'upload' {
request-body -> (:$id is copy, :$auth is copy, :$images) {
$id .= body-text;
$auth .= body-text;
my Bool $skip-loop;
my IO() $user-store = "%s/%s".sprintf: $store, $id;
if "$user-store/auth".IO.slurp ne $auth {
response.status = 401;
$skip-loop = True;
}
my @res;
IMAGE: for @($images) -> $img {
last IMAGE if $skip-loop;
my Bool $stored = True;
my Str @messages;
@messages.push("Max file size exceeded")
if $img.body-blob.bytes > 2097152; # 1024 * 1024 * 2
@messages.push("Only png/jpeg allowed")
if $img.content-type ne "image/png"|"image/jpeg";
$stored = False if @messages.elems;
if $stored {
my Str $filename = ('a'...'z', 'A'...'Z', 0...9).roll(16).join;
spurt "$user-store/images/$filename", $img.body-blob;
}
push @res, %(
filename => $img.filename,
:@messages, :$stored
);
}
content 'application/json', @res;
}
}
get -> 'smile', $id {
my IO() $user-store = "%s/%s".sprintf: $store, $id;
my $img;
if "$user-store/images".IO.d {
my @imgs = dir("$user-store/images").grep(*.f);
if @imgs.elems {
$img = @imgs.pick(1).first;
} else {
response.status = 406;
}
} else {
response.status = 404;
}
if $img {
static $img;
$img.unlink;
} else {
content 'text/plain', '';
}
}
# Serving static assets.
# Quick fix for an issue.
get -> 'js', *@path { static 'dist/js', @path; }
get -> 'css', *@path { static 'dist/css', @path; }
get -> 'img', *@path { static 'dist/img', @path; }
get -> 'fonts', *@path { static 'dist/fonts', @path; }
get -> $x, 'js', *@path { static 'dist/js', @path; }
get -> $x, 'css', *@path { static 'dist/css', @path; }
get -> $x, 'img', *@path { static 'dist/img', @path; }
get -> $x, 'fonts', *@path { static 'dist/fonts', @path; }
# Serve the app on all paths, it'll handle the routing.
get -> *@path {
static 'dist/index.html';
}
};
my $host = "0.0.0.0";
my $port = 9090;
my Cro::Service $http = Cro::HTTP::Server.new(
http => <1.1>,
host => $host,
port => $port,
:$application,
after => [
Cro::HTTP::Log::File.new(logs => $*OUT, errors => $*ERR)
]
);
$http.start;
put "Listening at http://{$host}:{$port}";
react {
whenever signal(SIGINT) {
say "Shutting down...";
$http.stop;
done;
}
}