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}