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