// compute blake2 hash of message id func (msgid MessageID) Blake2Hash() string { h := crypto.Hash() io.WriteString(h, msgid.String()) return strings.ToLower(fmt.Sprintf("%x", h.Sum(nil))) }
// store attachment onto filesystem func (fs FilesystemStorage) StoreAttachment(r io.Reader, filename string) (fpath string, err error) { // open temp file for storage var tf *os.File tf, err = fs.obtainTempFile() if err == nil { // we have the temp file // close tempfile when done defer tf.Close() // create hasher h := crypto.Hash() // create multiwriter mw := io.MultiWriter(tf, h) log.WithFields(log.Fields{ "pkg": "fs-store", "filename": filename, }).Debug("writing to disk") var n int64 // write all of the reader to the multiwriter n, err = io.Copy(mw, r) if err == nil { // successful write // get file checksum d := h.Sum(nil) // rename file to hash + extension from filename fpath = base32.StdEncoding.EncodeToString(d) + filepath.Ext(filename) fpath = filepath.Join(fs.AttachmentDir(), fpath) _, err = os.Stat(fpath) // is that file there? if os.IsNotExist(err) { // it's not there, let's write it var f *os.File f, err = os.OpenFile(fpath, os.O_WRONLY, 0755) if err == nil { // file opened defer f.Close() // seek to beginning of tempfile tf.Seek(0, os.SEEK_SET) // write all of the temp file to the storage file n, err = io.Copy(f, tf) // if err == nil by here it's all good l := log.WithFields(log.Fields{ "pkg": "fs-store", "filename": filename, "hash": d, "filepath": fpath, "size": n, }) if err == nil { l.Debug("wrote attachment to disk") } else { l.Error("failed to write attachment to disk", err) } } else { log.WithFields(log.Fields{ "pkg": "fs-store", "filename": filename, "hash": d, "filepath": fpath, }).Error("failed to open file") } } else { log.WithFields(log.Fields{ "pkg": "fs-store", "filename": filename, "hash": d, "filepath": fpath, "size": n, }).Debug("attachment exists on disk") } } } else { log.WithFields(log.Fields{ "pkg": "fs-store", "filename": filename, }).Error("cannot open temp file for attachment", err) } return }