X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=main.go;h=8a39053dc18444de2601b8a93039f6dde57cca8f;hb=b9b48a3e2d1c9dca2e0b2c9668e69dc892a2efee;hp=e3740f9a2ebac73e13d4f5a84fff63d64aee3d79;hpb=0e2d904b168b0779e9131b31410daebd73764e28;p=uploader.git diff --git a/main.go b/main.go index e3740f9..8a39053 100644 --- a/main.go +++ b/main.go @@ -35,10 +35,11 @@ import ( "os/exec" "strconv" "strings" + "sync" "time" "go.cypherpunks.ru/recfile" - "go.cypherpunks.ru/tai64n" + "go.cypherpunks.ru/tai64n/v2" "golang.org/x/crypto/blake2b" "golang.org/x/net/netutil" ) @@ -57,7 +58,7 @@ var ( Example command line usage:
 $ curl -F file=@somedata.tar.gpg [-F comment="optional comment"] http://.../upload/
-$ b2sum -a blake2b somedata.tar.gpg # to verify checksum
+$ b2sum somedata.tar.gpg # to verify BLAKE2b-512 checksum
 

@@ -68,9 +69,11 @@ $ b2sum -a blake2b somedata.tar.gpg # to verify checksum
`)) NotifyFromAddr *string NotifyToAddr *string + Jobs sync.WaitGroup ) func notify(tai, filename string, size int64, comment string) { + defer Jobs.Done() if *NotifyToAddr == "" { return } @@ -130,8 +133,8 @@ func upload(w http.ResponseWriter, r *http.Request) { } t := time.Now() ts := new(tai64n.TAI64N) - tai64n.FromTime(t, ts) - tai := ts.Encode()[1:] + ts.FromTime(t) + tai := tai64n.Encode(ts[:])[1:] fnOrig := p.FileName() fd, err := os.OpenFile(tai+".part", os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0666) if err != nil { @@ -181,41 +184,70 @@ func upload(w http.ResponseWriter, r *http.Request) { } io.Copy(w, &rec) log.Println(r.RemoteAddr, tai, fnOrig, n, sum) + + rec.Reset() + wr = recfile.NewWriter(&rec) + if _, err = wr.WriteFields( + recfile.Field{Name: "Filename", Value: fnOrig}, + ); err != nil { + log.Println(r.RemoteAddr, tai, fnOrig, n, sum, err) + return + } + + var comment []byte p, err = mr.NextPart() if err != nil || p.FormName() != CommentFieldName { - go notify(fnOrig, tai, n, "") - return + goto Notify } - comment, err := ioutil.ReadAll(p) + comment, err = ioutil.ReadAll(p) if err != nil || len(comment) == 0 { - go notify(tai, fnOrig, n, "") - return + goto Notify } - ioutil.WriteFile(tai+".txt", comment, os.FileMode(0666)) + wr.WriteFieldMultiline("Comment", strings.Split(string(comment), "\n")) + +Notify: + Jobs.Add(1) go notify(tai, fnOrig, n, string(comment)) + ioutil.WriteFile(tai+".rec", rec.Bytes(), os.FileMode(0666)) } func main() { + doUCSPI := flag.Bool("ucspi", false, "Work as UCSPI-TCP service") 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 sent to") NotifyToAddr = flag.String("notify-to", "", "Address notifications are sent from") flag.Parse() log.SetFlags(log.Lshortfile) - log.SetOutput(os.Stdout) + if !*doUCSPI { + log.SetOutput(os.Stdout) + } 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 { - log.Fatalln(err) - } - log.Println("listening", *bind) - ln = netutil.LimitListener(ln, *conns) s := &http.Server{ ReadHeaderTimeout: 10 * time.Second, MaxHeaderBytes: 10 * (1 << 10), } http.HandleFunc("/upload/", upload) - s.Serve(ln) + if *doUCSPI { + s.SetKeepAlivesEnabled(false) + ln := &UCSPI{} + s.ConnState = connStater + err := s.Serve(ln) + if _, ok := err.(UCSPIAlreadyAccepted); !ok { + log.Fatalln(err) + } + Jobs.Wait() + } else { + ln, err := net.Listen("tcp", *bind) + if err != nil { + log.Fatalln(err) + } + log.Println("listening", *bind) + ln = netutil.LimitListener(ln, *conns) + if err = s.Serve(ln); err != nil { + log.Fatalln(err) + } + } }