From 4cf829bd25c3f01a45e1823bb8d07d0fb660d98a Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Thu, 30 May 2019 20:59:09 +0300 Subject: [PATCH] Ability to send notification about uploaded files --- README | 2 ++ src/uploader/main.go | 49 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/README b/README index 5d674a9..9f5cf19 100644 --- a/README +++ b/README @@ -11,3 +11,5 @@ You can upload files with curl: You can verify integrity locally: b2sum -a blake2b somedata.tar.gpg + +You can enable mail notification with -notify-to and -notify-from options. diff --git a/src/uploader/main.go b/src/uploader/main.go index a1465cd..788c2ca 100644 --- a/src/uploader/main.go +++ b/src/uploader/main.go @@ -7,15 +7,20 @@ package main import ( "bufio" + "encoding/base64" "encoding/hex" "flag" "fmt" "html/template" "io" + "io/ioutil" "log" + "mime" "net" "net/http" "os" + "os/exec" + "strings" "time" "golang.org/x/crypto/blake2b" @@ -26,6 +31,8 @@ const ( WriteBufSize = 1 << 20 FileFieldName = "fileupload" CommentFieldName = "comment" + + SendmailCmd = "/usr/sbin/sendmail" ) var ( @@ -37,8 +44,41 @@ var (
`)) + NotifyFromAddr *string + NotifyToAddr *string ) +func notify(timestamp string, size int64, comment string) { + if *NotifyToAddr == "" { + return + } + cmd := exec.Command(SendmailCmd, *NotifyToAddr) + cmd.Stdin = io.MultiReader( + strings.NewReader(fmt.Sprintf( + `From: %s +To: %s +Subject: %s +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf-8 +Content-Transfer-Encoding: base64 + +`, + *NotifyFromAddr, + *NotifyToAddr, + mime.BEncoding.Encode("UTF-8", fmt.Sprintf( + "%s (%d KiB)", timestamp, size/1024, + )), + )), + strings.NewReader(base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf( + "Timestamp: %s\nSize: %d bytes\nComment: %s\n", + timestamp, + size, + comment, + )))), + ) + cmd.Run() +} + func upload(w http.ResponseWriter, r *http.Request) { log.Println(r.RemoteAddr, "connected") if r.Method == http.MethodGet { @@ -101,10 +141,12 @@ func upload(w http.ResponseWriter, r *http.Request) { log.Println(r.RemoteAddr, fn, p.FileName(), n, sum) p, err = mr.NextPart() if err != nil || p.FormName() != CommentFieldName { + go notify(fn, n, "") return } comment, err := ioutil.ReadAll(p) if err != nil || len(comment) == 0 { + go notify(fn, n, "") return } ioutil.WriteFile(fn+".txt", comment, os.FileMode(0600)) @@ -114,10 +156,15 @@ func upload(w http.ResponseWriter, r *http.Request) { func main() { bind := flag.String("bind", "[::]:8086", "Address to bind to") conns := flag.Int("conns", 2, "Maximal number of connections") + NotifyFromAddr = flag.String("notify-from", "uploader@example.com", "Address notifications are send to") + NotifyToAddr = flag.String("notify-to", "", "Address notifications are send from") flag.Parse() + if len(*NotifyFromAddr) == 0 && len(*NotifyToAddr) > 0 { + log.Fatalln("notify-from address can not be empty, if notify-to is set") + } ln, err := net.Listen("tcp", *bind) if err != nil { - panic(err) + log.Fatalln(err) } log.Println("listening", *bind) ln = netutil.LimitListener(ln, *conns) -- 2.44.0