all repos — fsrv @ 77998d755ff6c1331440e85d4271abbb986c2b61

filehost server for x.icyphox.sh

main.go (view raw)

 1package main
 2
 3import (
 4	"flag"
 5	"fmt"
 6	"io"
 7	"log"
 8	"math/rand"
 9	"net/http"
10	"os"
11	"path/filepath"
12	"time"
13)
14
15type settings struct {
16	url       string
17	port      string
18	namelen   int
19	key       string
20	storepath string
21	index     string
22}
23
24func randName(n int) string {
25	letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890~-")
26	b := make([]rune, n)
27	for i := range b {
28		b[i] = letters[rand.Intn(len(letters))]
29	}
30	return string(b)
31}
32
33func (s *settings) uploadFile(w http.ResponseWriter, r *http.Request) {
34	switch r.Method {
35	case "POST":
36		key := r.FormValue("key")
37		fmt.Println(key)
38		if key != s.key {
39			fmt.Fprintf(w, "incorrect key")
40			log.Printf("incorrect key: %+v", key)
41			return
42		}
43		r.ParseMultipartForm(10 << 20)
44		file, handler, err := r.FormFile("file")
45		if err != nil {
46			log.Println(err)
47			return
48		}
49		defer file.Close()
50		log.Printf("file: %+v\t%+v bytes", handler.Filename, handler.Size)
51
52		ext := filepath.Ext(handler.Filename)
53		fileBytes, err := io.ReadAll(file)
54		if err != nil {
55			log.Println(err)
56		}
57
58		newFile := randName(5) + ext
59		diskFile := filepath.Join(s.storepath, newFile)
60		os.WriteFile(diskFile, fileBytes, 0644)
61		log.Printf("wrote: %+v", diskFile)
62
63		fileUrl := s.url + "/" + newFile
64		fmt.Fprintf(w, "%v", fileUrl)
65	case "GET":
66		http.ServeFile(w, r, s.index)
67	default:
68		fmt.Fprintf(w, "unsupported method")
69	}
70}
71
72func (s *settings) readSettings() {
73	flag.StringVar(&s.url, "url", "localhost", "url for fsrv to serve files")
74	flag.StringVar(&s.port, "port", "9393", "port to listen on")
75	flag.StringVar(&s.storepath, "storepath", "uploads", "path to store uploaded files")
76	flag.IntVar(&s.namelen, "namelen", 5, "length of random filename")
77	flag.StringVar(&s.key, "key", "secret", "secret key; generate this yourself")
78	flag.StringVar(&s.index, "index", "index.html", "path to index html file")
79	flag.Parse()
80}
81
82func main() {
83	rand.Seed(time.Now().UnixNano())
84
85	st := settings{}
86	st.readSettings()
87
88	http.HandleFunc("/", st.uploadFile)
89
90	log.Println("listening on " + st.port)
91	http.ListenAndServe(":"+st.port, nil)
92}