.gitmodules | 6 ++++++ README | 3 +++ src/uploader/main.go | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000000000000000000000000000000000..b031076d2285fe5f1230e62250a88d1e67d1109b --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "src/golang.org/x/net"] + path = src/golang.org/x/net + url = https://go.googlesource.com/net +[submodule "src/golang.org/x/crypto"] + path = src/golang.org/x/crypto + url = https://go.googlesource.com/crypto diff --git a/README b/README new file mode 100644 index 0000000000000000000000000000000000000000..b97d1adfc6feaca7e545b7784e9b7898e8c913ad --- /dev/null +++ b/README @@ -0,0 +1,3 @@ +Simplest form file uploader. +It just saves uploaded file from HTML form to the new file on the disk. +Also it calculates BLAKE2s checksum, replying with it in the answer. diff --git a/src/uploader/main.go b/src/uploader/main.go new file mode 100644 index 0000000000000000000000000000000000000000..43794c63f18fed4ae88d1848083ae0a9ac60baf2 --- /dev/null +++ b/src/uploader/main.go @@ -0,0 +1,91 @@ +/* +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) +}