/* uploader -- simplest form file uploader Copyright (C) 2018 Sergey Matveev */ package main import ( "bufio" "encoding/hex" "flag" "fmt" "io" "net" "net/http" "os" "time" "golang.org/x/crypto/blake2s" "golang.org/x/net/netutil" ) const ( WriteBufSize = 1 << 20 ) func upload(w http.ResponseWriter, r *http.Request) { if r.Method == http.MethodGet { w.Write([]byte(` Upload
`)) return } mr, err := r.MultipartReader() if err != nil { fmt.Println(err) return } p, err := mr.NextPart() if err != nil { fmt.Println(err) return } if p.FormName() != "fileupload" { fmt.Println("non file form field") return } now := time.Now() fd, err := os.OpenFile(now.Format(time.RFC3339Nano), os.O_WRONLY|os.O_CREATE, 0600) if err != nil { fmt.Println(err) return } defer fd.Close() h, err := blake2s.New256(nil) if err != nil { panic(err) } fdBuf := bufio.NewWriterSize(fd, WriteBufSize) mw := io.MultiWriter(fdBuf, h) n, err := io.Copy(mw, p) if err != nil { fmt.Println(err) return } if err = fdBuf.Flush(); err != nil { fmt.Println(err) return } fmt.Fprintf(w, "bytes: %d\nBLAKE2s: %s\n", n, hex.EncodeToString(h.Sum(nil))) } func main() { bind := flag.String("bind", "[::]:8086", "Address to bind to") conns := flag.Int("conns", 2, "Maximal number of connections") flag.Parse() ln, err := net.Listen("tcp", *bind) if err != nil { panic(err) } fmt.Println("listening on", *bind) ln = netutil.LimitListener(ln, *conns) s := &http.Server{ ReadHeaderTimeout: 10 * time.Second, MaxHeaderBytes: 10 * (1 << 10), } http.HandleFunc("/upload/", upload) s.Serve(ln) }