summaryrefslogtreecommitdiff
path: root/posts/tmpfilehost.md
blob: 5249d8e7adf48572a46d5d8d20c30ec26dd5e3b9 (plain)
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
title: Creating a Temporary File Hoster
date: 2022-04-27 12:00
---
For the past couple years, whenever I wanted to upload a file, I would
curl the file to [lainsafe](https://git.qorg11.net/lainsafe.git/), [i/u.kalli.st](https://gt.kalli.st/kallist/uploader), and recently [ttm.sh](https://tildegit.org/tildeverse/ttm.sh).

Since I want to selfhost, I thought i can just use either of what those
three used. Earlier today though, I realized I could just copy the
file(s) I want to upload via rsync/scp to a public directory that gets
served by an httpd or gopherd.

From what I understand, the previous file hosters had a program running
that read the file that the user uploads to them, does some renaming,
and writes that to a directory that is served. After some time, that
file is deleted. The first part can be handled via rsync/scp like
mentioned previously. For automatic deletion, I recently saw in find's
man page that it can list that haven't been modified via the -mtime
flag, so that can be used with a cron job.

But while thinking of this idea, I got stumped by how to print back the
url to this file that is uploaded since printing the filename as is
appended to its baseurl, there could be spaces and other invalid
unescaped characters which programs trying to download it may not like.

I thought I could just create a separate program for this. However,
doing this seemed more complicated than just copying the file to the
server. So, with the help of awk and some StackExchanging, I've been
able to do it.

`upfile.sh`:
```sh
#!/bin/sh
urlencode() {
     awk '
BEGIN { for (i = 1; i < 256; i++) hex[sprintf("%c", i)] = sprintf("%%%02X", i) }
{
     for (i = 1; i <= length($0); i++) {
             c = substr($0, i, 1)
             printf("%s", c ~ /^[-._~0-9a-zA-Z]$/ ? c : hex[c])
     }
     printf "\n"
}
'
}

FILE="$1"
SERVER="REPLACEME"
BASEURL="https://u.$SERVER"

[ -z "$1" ] && exit 1

scp "$FILE" "$SERVER":files/ || exit 1
printf "%s/" "$BASEURL"
basename "$FILE" | urlencode
```

Then to purge these files after they become too old (e.g. 3 days), you
can put something like this in a cron job to run daily (replace file
directory):

```
0 0 * * * find /path/to/dir/ -mtime +3 -exec rm {} \;
```

You can also put this command in /etc/daily.local or /etc/cron/daily,
or whatever file your root crontab's @daily runs (if there is one).

And that's it! The only difficult part that I experienced was encoding
the name of the file and originally did that in C. However, having a
mixed C and shell program just for file uploading didn't sit right with
me. It seems like whenever you're in doubt, you can rely on awk huh.