/
tarballs
executable file
·97 lines (85 loc) · 2.11 KB
/
tarballs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#!/usr/bin/env perl6
my %*SUB-MAIN-OPTS = :named-anywhere;
use OpenSSL::CryptTools;
my $iv = %*ENV<tarballs_iv>;
my $key = %*ENV<tarballs_key>;
die 「you gotta pass tarballs_iv and tarballs_key as env vars」
unless $iv and $key;
$iv .= encode;
$key .= encode;
my &pad = {
.chars == 1
?? "0$_"
!! $_
}
sub encrypt-path ($path) {
@(encrypt($path.encode, :aes256, :$iv, :$key))
.hyper.map({pad(.base(36))})
.join(「」)
.lc;
}
sub decrypt-pathword ($pathword) {
my $buf = Buf.new;
my @ints = $pathword
.comb(2)
.map({.parse-base(36)});
for @ints {
$buf.append($_);
};
return decrypt($buf, :aes256, :$iv, :$key).decode;
}
sub untar (Blob $tarball, Str $path) {
my $tar = Proc::Async.new: :w, 「tar」, 「-U」, 「-C」, $path, 「-xzv」;
my $completion = $tar.start;
$tar.write($tarball);
$tar.close-stdin;
await $completion;
}
multi MAIN (「encrypt」, $path) {
say encrypt-path($path);
}
multi MAIN (「decrypt」, $pathword) {
say decrypt-pathword($pathword);
}
multi MAIN (
「serve」,
Str :$prefix = $*CWD.Str, #= the root to start extractions from
Str :$suffix = 「application」, #= the suffix to add to extraction targets
Int :$port = 7440, #= port to bind to
Str :$host = 「localhost」 #= host to bind to
) {
use Cro::HTTP::Server;
use Cro::HTTP::Router;
my $application := route {
get -> {
content 「text/html」, q:to/index.html/
<!doctype html>
<style>{font-family: avenir next; font-color: #333;}</style>
<body bgcolor=#fe8>
<form method="POST" action="/" enctype="multipart/form-data">
<input type="text" name="pathword">
<input type="file" name="ball">
<input type="submit">
</form>
index.html
}
post -> {
request-body -> (:$pathword, :$ball, *%rest) {
my $path = "{$prefix}/{decrypt-pathword($pathword.Str)}/{$suffix}";
my $filename = $ball.filename;
untar($ball.body-blob, $path);
content 「text/plain」, 「thanks」;
}
}
}
my Cro::Service \service := Cro::HTTP::Server.new(
:host($host),
:port($port),
:$application
);
service.start;
react whenever signal(SIGINT) {
service.stop;
exit;
}
}