diff options
Diffstat (limited to 'roseh.moe.go')
| -rw-r--r-- | roseh.moe.go | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/roseh.moe.go b/roseh.moe.go index 55e2682..b134de0 100644 --- a/roseh.moe.go +++ b/roseh.moe.go @@ -265,15 +265,22 @@ func writeHoleFile(part *multipart.Part) (string, error) { return hole, f.Close() } -func decryptedSize(size int64) int64 { - size -= 32 - segments := (size + (blockSize - 1)) / blockSize - return size - segments*16 +type offsetReader struct { + io.ReadSeeker + offset int +} + +func (r *offsetReader) Seek(offset int64, whence int) (int64, error) { + if whence == io.SeekStart { + offset += int64(r.offset) + } + n, err := r.ReadSeeker.Seek(offset, whence) + return n - int64(r.offset), err } var errNoHole = errors.New("no such hole") -func readHoleFile(w http.ResponseWriter, hole string) error { +func readHoleFile(w http.ResponseWriter, req *http.Request, hole string) error { key, err := hkdf.Key(sha256.New, []byte(hole), nil, "", 48) if err != nil { return err @@ -287,10 +294,6 @@ func readHoleFile(w http.ResponseWriter, hole string) error { return err } defer f.Close() - stat, err := f.Stat() - if err != nil { - return err - } r := oae2.NewReader(f, encryptionKey, blockSize) buf := make([]byte, 8) if _, err := io.ReadFull(r, buf); err != nil { @@ -303,10 +306,12 @@ func readHoleFile(w http.ResponseWriter, hole string) error { } fileName := string(buf) w.Header().Set("Content-Disposition", "attachment; filename*=UTF-8''"+fileName) - fileSize := decryptedSize(stat.Size()) - 8 - int64(fileNameLen) - w.Header().Set("Content-Length", strconv.FormatInt(fileSize, 10)) - _, err = io.Copy(w, r) - return err + var modTime time.Time + if stat, err := f.Stat(); err == nil { + modTime = stat.ModTime() + } + http.ServeContent(w, req, fileName, modTime, &offsetReader{r, 8 + int(fileNameLen)}) + return nil } func wormhole(w http.ResponseWriter, r *http.Request) { @@ -362,7 +367,7 @@ func wormholeUpload(w http.ResponseWriter, r *http.Request) { } func wormholeDownload(w http.ResponseWriter, r *http.Request) { - if err := readHoleFile(w, r.PathValue("hole")); err != nil { + if err := readHoleFile(w, r, r.PathValue("hole")); err != nil { if err == errNoHole { notFound(w, r) return |
