#!/usr/bin/env raku unit sub MAIN(Str :a(:$address) = '127.0.0.1', #= bind to this address UInt :p(:$port) = 9999, #= bind to this port Str :d(:$directory) is required #= serve this directory ); $directory.IO.mkdir; react { my $server = do whenever IO::Socket::Async.listen($address, $port) -> $client { my $client_address = "{$client.peer-host}:{$client.peer-port}"; say "[+] New client on $client_address"; my $in = $client.Supply.lines(:!chomp).Channel; # HTTP request or first line of data my $first_line = $in.receive; if $first_line ~~ rx/^ GET \s (.+) \s 'HTTP/1.1'/ { my $filename = $directory.IO.add($0); say "[+] $client_address <== $filename"; $client.print: "HTTP/1.1 200 OK\r\n\r\n"; $client.print: try { $filename.IO.slurp } // "Not found"; } else { my $filename = "{('A'..'Z').pick(**).head(10).join}{time}"; my @content = $first_line, |(try { $in.list } // ()); $directory.IO.add($filename).spurt(@content.join); say "[+] $client_address ==> $filename"; $client.say: "http://$address:$port/$filename"; } $client.close; } say "[+] Listening on $address:$port, serving: $directory"; whenever signal(SIGINT) { $server.close; say "\rBye !"; exit; } }