diff --git a/packages/http/file.go b/packages/http/file.go index 8aebee4..efda4d9 100644 --- a/packages/http/file.go +++ b/packages/http/file.go @@ -2,14 +2,17 @@ package http import ( "crypto/sha256" + "go-socket/packages/convertions" "go-socket/packages/globals" "go-socket/packages/minio" "io" "net/http" - - "go-socket/packages/convertions" ) +func handleExistingUpload() { + +} + func HandleFileUpload(response http.ResponseWriter, request *http.Request) { if !postValidCheckWithResponseOnFail(&response, request, true) { return @@ -36,14 +39,18 @@ func HandleFileUpload(response http.ResponseWriter, request *http.Request) { request.Body = http.MaxBytesReader(response, request.Body, int64(globals.MaxPostWithFileBytes)) multipartReader, err := request.MultipartReader() if err != nil { - http.Error(response, "expected multipart form", 400) + http.Error(response, "expected multipart form", http.StatusBadRequest) return } + uploaded := false for { part, err := multipartReader.NextPart() if err == io.EOF { - http.Error(response, "bad request", 400) + break + } + if err != nil { + http.Error(response, "bad request", http.StatusBadRequest) return } @@ -52,22 +59,35 @@ func HandleFileUpload(response http.ResponseWriter, request *http.Request) { continue } - if len(part.FileName()) != sha256.Size { + if len(part.FileName()) != sha256.Size*2 { part.Close() - http.Error(response, "filename must be sha256 of whole file", 400) + http.Error(response, "filename must be hex-encoded sha256 of whole file", http.StatusBadRequest) return } - err = minio.Upload(ctx, part.FileName(), part, -1, part.Header.Get("Content-Type"), user.Id) + contentType := part.Header.Get("Content-Type") + key := minio.GetKey(part.FileName(), contentType) + + if minio.DoesExist(ctx, key) { + part.Close() + uploaded = true + continue + } + + err = minio.Upload(ctx, key, part, -1, contentType, user.Id) + part.Close() if err != nil { http.Error(response, "upload failed", http.StatusInternalServerError) return } - part.Close() - if err != nil { - http.Error(response, "upload failed", 500) - return - } + uploaded = true } + + if !uploaded { + http.Error(response, "no file in request", http.StatusBadRequest) + return + } + + response.WriteHeader(http.StatusAccepted) } diff --git a/packages/minio/minio.go b/packages/minio/minio.go index 8b2877b..13d546e 100644 --- a/packages/minio/minio.go +++ b/packages/minio/minio.go @@ -35,7 +35,7 @@ func extensionFromContentType(ct string) string { return exts[0] } -func getKey(hash string, contentType string) string { +func GetKey(hash string, contentType string) string { return hash + extensionFromContentType(contentType) } @@ -78,15 +78,12 @@ func Upload(ctx context.Context, key string, body io.Reader, size int64, content return err } -func getDownloadUrl(ctx context.Context, key string) (*url.URL, error) { +func GetDownloadUrl(ctx context.Context, key string) (*url.URL, error) { u, err := minClient.PresignedGetObject(ctx, globals.FileStorageBucketName, key, globals.FileDownloadLinkTtl, nil) return u, err } func DoesExist(ctx context.Context, key string) bool { - _, err := minClient.GetObject(ctx, globals.FileStorageBucketName, key, minio.GetObjectOptions{}) - if err != nil { - return false - } - return true + _, err := minClient.StatObject(ctx, globals.FileStorageBucketName, key, minio.StatObjectOptions{}) + return err == nil }