summaryrefslogtreecommitdiff
path: root/posts/tmpfilehost.md
diff options
context:
space:
mode:
Diffstat (limited to 'posts/tmpfilehost.md')
-rw-r--r--posts/tmpfilehost.md71
1 files changed, 71 insertions, 0 deletions
diff --git a/posts/tmpfilehost.md b/posts/tmpfilehost.md
new file mode 100644
index 0000000..5249d8e
--- /dev/null
+++ b/posts/tmpfilehost.md
@@ -0,0 +1,71 @@
1title: Creating a Temporary File Hoster
2date: 2022-04-27 12:00
3---
4For the past couple years, whenever I wanted to upload a file, I would
5curl 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).
6
7Since I want to selfhost, I thought i can just use either of what those
8three used. Earlier today though, I realized I could just copy the
9file(s) I want to upload via rsync/scp to a public directory that gets
10served by an httpd or gopherd.
11
12From what I understand, the previous file hosters had a program running
13that read the file that the user uploads to them, does some renaming,
14and writes that to a directory that is served. After some time, that
15file is deleted. The first part can be handled via rsync/scp like
16mentioned previously. For automatic deletion, I recently saw in find's
17man page that it can list that haven't been modified via the -mtime
18flag, so that can be used with a cron job.
19
20But while thinking of this idea, I got stumped by how to print back the
21url to this file that is uploaded since printing the filename as is
22appended to its baseurl, there could be spaces and other invalid
23unescaped characters which programs trying to download it may not like.
24
25I thought I could just create a separate program for this. However,
26doing this seemed more complicated than just copying the file to the
27server. So, with the help of awk and some StackExchanging, I've been
28able to do it.
29
30`upfile.sh`:
31```sh
32#!/bin/sh
33urlencode() {
34 awk '
35BEGIN { for (i = 1; i < 256; i++) hex[sprintf("%c", i)] = sprintf("%%%02X", i) }
36{
37 for (i = 1; i <= length($0); i++) {
38 c = substr($0, i, 1)
39 printf("%s", c ~ /^[-._~0-9a-zA-Z]$/ ? c : hex[c])
40 }
41 printf "\n"
42}
43'
44}
45
46FILE="$1"
47SERVER="REPLACEME"
48BASEURL="https://u.$SERVER"
49
50[ -z "$1" ] && exit 1
51
52scp "$FILE" "$SERVER":files/ || exit 1
53printf "%s/" "$BASEURL"
54basename "$FILE" | urlencode
55```
56
57Then to purge these files after they become too old (e.g. 3 days), you
58can put something like this in a cron job to run daily (replace file
59directory):
60
61```
620 0 * * * find /path/to/dir/ -mtime +3 -exec rm {} \;
63```
64
65You can also put this command in /etc/daily.local or /etc/cron/daily,
66or whatever file your root crontab's @daily runs (if there is one).
67
68And that's it! The only difficult part that I experienced was encoding
69the name of the file and originally did that in C. However, having a
70mixed C and shell program just for file uploading didn't sit right with
71me. It seems like whenever you're in doubt, you can rely on awk huh.