]> Sergey Matveev's repositories - uploader.git/blob - src/uploader/main.go
43794c63f18fed4ae88d1848083ae0a9ac60baf2
[uploader.git] / src / uploader / main.go
1 /*
2 uploader -- simplest form file uploader
3 Copyright (C) 2018 Sergey Matveev <stargrave@stargrave.org>
4 */
5
6 package main
7
8 import (
9         "bufio"
10         "encoding/hex"
11         "flag"
12         "fmt"
13         "io"
14         "net"
15         "net/http"
16         "os"
17         "time"
18
19         "golang.org/x/crypto/blake2s"
20         "golang.org/x/net/netutil"
21 )
22
23 const (
24         WriteBufSize = 1 << 20
25 )
26
27 func upload(w http.ResponseWriter, r *http.Request) {
28         if r.Method == http.MethodGet {
29                 w.Write([]byte(`<html>
30 <head><title>Upload</title></head><body>
31 <form enctype="multipart/form-data" action="/upload/" method="post">
32 <input type="file" name="fileupload" /><input type="submit" />
33 </form></body></html>`))
34                 return
35         }
36         mr, err := r.MultipartReader()
37         if err != nil {
38                 fmt.Println(err)
39                 return
40         }
41         p, err := mr.NextPart()
42         if err != nil {
43                 fmt.Println(err)
44                 return
45         }
46         if p.FormName() != "fileupload" {
47                 fmt.Println("non file form field")
48                 return
49         }
50         now := time.Now()
51         fd, err := os.OpenFile(now.Format(time.RFC3339Nano), os.O_WRONLY|os.O_CREATE, 0600)
52         if err != nil {
53                 fmt.Println(err)
54                 return
55         }
56         defer fd.Close()
57         h, err := blake2s.New256(nil)
58         if err != nil {
59                 panic(err)
60         }
61         fdBuf := bufio.NewWriterSize(fd, WriteBufSize)
62         mw := io.MultiWriter(fdBuf, h)
63         n, err := io.Copy(mw, p)
64         if err != nil {
65                 fmt.Println(err)
66                 return
67         }
68         if err = fdBuf.Flush(); err != nil {
69                 fmt.Println(err)
70                 return
71         }
72         fmt.Fprintf(w, "bytes: %d\nBLAKE2s: %s\n", n, hex.EncodeToString(h.Sum(nil)))
73 }
74
75 func main() {
76         bind := flag.String("bind", "[::]:8086", "Address to bind to")
77         conns := flag.Int("conns", 2, "Maximal number of connections")
78         flag.Parse()
79         ln, err := net.Listen("tcp", *bind)
80         if err != nil {
81                 panic(err)
82         }
83         fmt.Println("listening on", *bind)
84         ln = netutil.LimitListener(ln, *conns)
85         s := &http.Server{
86                 ReadHeaderTimeout: 10 * time.Second,
87                 MaxHeaderBytes:    10 * (1 << 10),
88         }
89         http.HandleFunc("/upload/", upload)
90         s.Serve(ln)
91 }