From 2df37e90020e6e6033212030851c1c10180787a5 Mon Sep 17 00:00:00 2001 From: skidoodle Date: Mon, 19 Jan 2026 00:33:09 +0100 Subject: [PATCH] fix: relax chunk limits, support proxies, optimize reads Signed-off-by: skidoodle --- internal/app/config.go | 1 + internal/app/server.go | 9 ++++++--- internal/app/upload.go | 4 ++-- internal/crypto/reader.go | 16 +++++++++++++--- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/internal/app/config.go b/internal/app/config.go index 7f87cf2..95949c6 100644 --- a/internal/app/config.go +++ b/internal/app/config.go @@ -22,6 +22,7 @@ const ( ShutdownTimeout = 10 * time.Second UploadChunkSize = 8 << 20 + MinChunkSize = 1 << 20 MaxRequestOverhead = 10 << 20 PermUserRWX = 0o700 MegaByte = 1 << 20 diff --git a/internal/app/server.go b/internal/app/server.go index 8fd3e52..d64bdf0 100644 --- a/internal/app/server.go +++ b/internal/app/server.go @@ -72,9 +72,12 @@ func (app *App) RespondWithLink(writer http.ResponseWriter, request *http.Reques return } - scheme := "https" - if request.TLS == nil { - scheme = "http" + scheme := request.Header.Get("X-Forwarded-Proto") + if scheme == "" { + scheme = "https" + if request.TLS == nil { + scheme = "http" + } } if _, err := fmt.Fprintf(writer, "%s://%s\n", scheme, link); err != nil { diff --git a/internal/app/upload.go b/internal/app/upload.go index 978ee9d..b1e4253 100644 --- a/internal/app/upload.go +++ b/internal/app/upload.go @@ -112,7 +112,7 @@ func (app *App) HandleChunk(writer http.ResponseWriter, request *http.Request) { return } - maxChunks := int((app.Conf.MaxMB*MegaByte)/UploadChunkSize) + ChunkSafetyMargin + maxChunks := int((app.Conf.MaxMB*MegaByte)/MinChunkSize) + ChunkSafetyMargin if !reUploadID.MatchString(uid) || idx > maxChunks || idx < 0 { app.SendError(writer, request, http.StatusBadRequest) @@ -148,7 +148,7 @@ func (app *App) HandleFinish(writer http.ResponseWriter, request *http.Request) return } - maxChunks := int((app.Conf.MaxMB*MegaByte)/UploadChunkSize) + ChunkSafetyMargin + maxChunks := int((app.Conf.MaxMB*MegaByte)/MinChunkSize) + ChunkSafetyMargin if !reUploadID.MatchString(uid) || total > maxChunks || total <= 0 { app.SendError(writer, request, http.StatusBadRequest) diff --git a/internal/crypto/reader.go b/internal/crypto/reader.go index c0dd702..46bb477 100644 --- a/internal/crypto/reader.go +++ b/internal/crypto/reader.go @@ -16,6 +16,7 @@ type Decryptor struct { aead cipher.AEAD size int64 offset int64 + phyOffset int64 } func NewDecryptor(readSeeker io.ReadSeeker, aead cipher.AEAD, encryptedSize int64) *Decryptor { @@ -35,6 +36,7 @@ func NewDecryptor(readSeeker io.ReadSeeker, aead cipher.AEAD, encryptedSize int6 aead: aead, size: plainSize, offset: 0, + phyOffset: -1, } } @@ -49,14 +51,22 @@ func (d *Decryptor) Read(buf []byte) (int, error) { overhead := int64(d.aead.Overhead()) actualChunkSize := int64(GCMChunkSize) + overhead - _, err := d.readSeeker.Seek(chunkIdx*actualChunkSize, io.SeekStart) - if err != nil { - return 0, fmt.Errorf("failed to seek: %w", err) + targetOffset := chunkIdx * actualChunkSize + + if d.phyOffset != targetOffset { + if _, err := d.readSeeker.Seek(targetOffset, io.SeekStart); err != nil { + return 0, fmt.Errorf("failed to seek: %w", err) + } + d.phyOffset = targetOffset } encrypted := make([]byte, actualChunkSize) bytesRead, err := io.ReadFull(d.readSeeker, encrypted) + if bytesRead > 0 { + d.phyOffset += int64(bytesRead) + } + if err != nil && !errors.Is(err, io.ErrUnexpectedEOF) { return 0, fmt.Errorf("failed to read encrypted data: %w", err) }