#!/usr/bin/perl # This file is part of sakisafe. use if $^O eq "openbsd", OpenBSD::Pledge, qw(pledge); use Mojolicious::Lite -signatures; use Mojolicious::Routes::Pattern; use List::MoreUtils qw(uniq); use Carp; use Term::ANSIColor; use English; use MIME::Types; use warnings; use experimental 'signatures'; use feature 'say'; plugin 'RenderFile'; my $openbsd = 0; $openbsd = 1 if $^O eq "openbsd"; pledge("stdio cpath rpath wpath inet flock fattr") if $openbsd; my $MAX_SIZE = 1024 * 1024 * 100; my @BANNED = qw(); # Add banned IP addresses here my $dirname; my $host; mkdir "f"; # Function to handle file uploads sub logger ( $level, $address, $message ) { open( my $fh, ">>", "sakisafe.log" ); printf( $fh "[%s]: %s has uploaded file %s\n", $level, $address, $message ); close($fh); } sub handle_file { my $c = shift; my $filedata = $c->param("file"); if ( $filedata->size > $MAX_SIZE ) { return $c->render( text => "Max upload size: $MAX_SIZE", status => 400 ); } if ( List::MoreUtils::any { /$c->tx->remote_address/ } uniq @BANNED ) { $c->render( text => "Hi! Seems like the server admin added your IP address to the banned IP array." . "As the developer of sakisafe, I can't do anything.", status => 403 ); return; } # Generate random string for the directory my @chars = ( '0' .. '9', 'a' .. 'Z' ); $dirname .= $chars[ rand @chars ] for 1 .. 5; my $filename = $filedata->filename; carp(color("bold yellow"), "sakisafe warning: could not create directory: $ERRNO", color("reset")) unless mkdir( "f/" . $dirname ); $filename .= ".txt" if $filename eq "-"; $filedata->move_to( "f/" . $dirname . "/" . $filename ); my $host = $c->req->url->to_abs->host; $c->res->headers->header( 'Location' => "http://$host/$dirname/" . $filename ); $c->render( text => "http://$host/f/$dirname/" . $filename, status => 201, ); logger( "INFO", $c->tx->remote_address, $dirname . "/" . $filename ); $dirname = ""; } # Function to log uploaded files get '/' => 'index'; post '/' => sub ($c) { handle_file($c) }; # Allow files to be downloaded. get '/f/:dir/#name' => sub ($c) { my $dir = $c->param("dir"); my $file = $c->param("name"); print $dir, $file . "\n"; my $ext = $file; $ext =~ s/.*\.//; $c->render_file( filepath => "f/".$dir . "/" . $file, format => 'jpg', content_disposition => 'inline' ); }; app->max_request_size( 1024 * 1024 * 100 ); post '/upload' => sub ($c) { handle_file($c) }; app->start; # Index template #By default Mojolicious gets the "directory root" from the "public" # directory, so the css and the favicon from the "public" directory, # in the root of this repo. __DATA__ @@ index.html.ep
POST a file:
curl -F 'file=@yourfile.png' https://<%= $c->req->url->to_abs->host; %>
Post your text directly
curl -F 'file=@-' https://<%= $c->req->url->to_abs->host; %>