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