From: Sergey Matveev Date: Mon, 8 Jan 2018 18:27:05 +0000 (+0300) Subject: Initial commit X-Git-Tag: v1.0.0~15 X-Git-Url: http://www.git.stargrave.org/?p=uploader.git;a=commitdiff_plain;h=ba3dcfbc5909e36646408b2c396ee7324b6f6fb1 Initial commit --- ba3dcfbc5909e36646408b2c396ee7324b6f6fb1 diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..b031076 --- /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 0000000..b97d1ad --- /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/golang.org/x/crypto b/src/golang.org/x/crypto new file mode 160000 index 0000000..0fcca48 --- /dev/null +++ b/src/golang.org/x/crypto @@ -0,0 +1 @@ +Subproject commit 0fcca4842a8d74bfddc2c96a073bd2a4d2a7a2e8 diff --git a/src/golang.org/x/net b/src/golang.org/x/net new file mode 160000 index 0000000..434ec0c --- /dev/null +++ b/src/golang.org/x/net @@ -0,0 +1 @@ +Subproject commit 434ec0c7fe3742c984919a691b2018a6e9694425 diff --git a/src/uploader/main.go b/src/uploader/main.go new file mode 100644 index 0000000..43794c6 --- /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) +}