site_vineetk

Source for vineetk.net website
Log | Files | Refs | LICENSE

tmpfilehost.md (2646B)


      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.