main.go (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
package main import ( "flag" "fmt" "io" "log" "math/rand" "net/http" "os" "path/filepath" "strings" "time" "github.com/alexedwards/flow" ) type settings struct { url string addr string namelen int key string storepath string index string } func randName(n int) string { letters := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890~-") b := make([]rune, n) for i := range b { b[i] = letters[rand.Intn(len(letters))] } return string(b) } func getKey(r *http.Request) string { var key string key = r.FormValue("key") if key == "" { header := r.Header.Get("Authorization") split := strings.Split(header, " ") if len(split) == 2 { key = split[1] } } return key } func (s *settings) upload(w http.ResponseWriter, r *http.Request) { key := getKey(r) useragent := r.Header.Get("User-Agent") if key != s.key { fmt.Fprintf(w, "incorrect key") log.Printf("incorrect key: %+v", key) return } r.ParseMultipartForm(512 << 20) file, handler, err := r.FormFile("file") if err != nil { log.Println(err) return } defer file.Close() log.Printf("file: %+v\t%+v bytes", handler.Filename, handler.Size) ext := filepath.Ext(handler.Filename) fileBytes, err := io.ReadAll(file) if err != nil { log.Println(err) } newFile := randName(5) + ext diskFile := filepath.Join(s.storepath, newFile) os.WriteFile(diskFile, fileBytes, 0644) log.Printf("wrote: %+v", diskFile) abs, err := filepath.Abs(diskFile) if err != nil { log.Println(err) } runHooks(abs) fileUrl := s.url + "/" + newFile if strings.Contains(useragent, "curl/") || strings.Contains(useragent, "Igloo/") { fmt.Fprintf(w, "%v", fileUrl) } else { http.Redirect(w, r, fileUrl, http.StatusSeeOther) } } func (s *settings) indexpage(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, s.index) } func (s *settings) readSettings() { flag.StringVar(&s.url, "url", "localhost", "url for fsrv to serve files") flag.StringVar(&s.addr, "addr", "0.0.0.0:9393", "address to listen on") flag.StringVar(&s.storepath, "storepath", "uploads", "path to store uploaded files") flag.IntVar(&s.namelen, "namelen", 5, "length of random filename") flag.StringVar(&s.key, "key", "secret", "secret key; generate this yourself") flag.StringVar(&s.index, "index", "index.html", "path to index html file") flag.Parse() } func main() { rand.Seed(time.Now().UnixNano()) mux := flow.New() st := settings{} st.readSettings() mux.HandleFunc("/", st.upload, "POST") mux.HandleFunc("/", st.indexpage, "GET") mux.Handle("/...", http.FileServer(nodirFileSystem{http.Dir(st.storepath)})) log.Println("listening on " + st.addr) http.ListenAndServe(st.addr, mux) } |