This commit is contained in:
gitGnome
2026-04-16 14:23:14 +02:00
parent 6d0eaa92e9
commit f0fdaedd8c
4 changed files with 28 additions and 154 deletions
+17 -56
View File
@@ -1,21 +1,14 @@
package http package http
import ( import (
"crypto/sha256"
"go-socket/packages/convertions" "go-socket/packages/convertions"
"go-socket/packages/globals" "go-socket/packages/globals"
"go-socket/packages/minio" "go-socket/packages/minio"
"go-socket/packages/postgresql"
"io"
"net/http" "net/http"
"github.com/google/uuid" "github.com/google/uuid"
) )
func handleExistingUpload() {
}
func HandleFileUpload(response http.ResponseWriter, request *http.Request) { func HandleFileUpload(response http.ResponseWriter, request *http.Request) {
if !postValidCheckWithResponseOnFail(&response, request, true) { if !postValidCheckWithResponseOnFail(&response, request, true) {
return return
@@ -28,6 +21,13 @@ func HandleFileUpload(response http.ResponseWriter, request *http.Request) {
return return
} }
request.Body = http.MaxBytesReader(response, request.Body, int64(globals.MaxPostWithFileBytes))
if err = request.ParseMultipartForm(int64(globals.MaxPostBytes)); err != nil {
http.Error(response, "invalid multipart form", http.StatusBadRequest)
return
}
connectionId, err := convertions.ConvertStringUuid(request.FormValue("connectionid")) connectionId, err := convertions.ConvertStringUuid(request.FormValue("connectionid"))
if err != nil { if err != nil {
http.Error(response, "invalid connectionid", http.StatusBadRequest) http.Error(response, "invalid connectionid", http.StatusBadRequest)
@@ -39,64 +39,25 @@ func HandleFileUpload(response http.ResponseWriter, request *http.Request) {
return return
} }
request.Body = http.MaxBytesReader(response, request.Body, int64(globals.MaxPostWithFileBytes)) file, header, err := request.FormFile("file")
multipartReader, err := request.MultipartReader()
if err != nil { if err != nil {
http.Error(response, "expected multipart form", http.StatusBadRequest) http.Error(response, "missing file", http.StatusBadRequest)
return return
} }
defer file.Close()
uploaded := false contentType := header.Header.Get("Content-Type")
for {
part, err := multipartReader.NextPart()
if err == io.EOF {
break
}
if err != nil {
http.Error(response, "bad request", http.StatusBadRequest)
return
}
if part.FileName() == "" { key :=
part.Close()
continue
}
if len(part.FileName()) != sha256.Size*2 { if err = minio.Upload(ctx, fileId.String(), file, header.Size, contentType, map[string]string{
part.Close() "orginalName": header.Filename,
http.Error(response, "filename must be hex-encoded sha256 of whole file", http.StatusBadRequest) "uploaderId": user.Id.String(),
return }); err != nil {
}
contentType := part.Header.Get("Content-Type")
key := minio.GetKey(part.FileName(), contentType)
if minio.DoesExist(ctx, key) {
part.Close()
uploaded = true
handleExistingUpload()
continue
}
id := uuid.New()
err = minio.Upload(ctx, key, part, -1, contentType, id)
postgresql.FileMetadataSave()
part.Close()
if err != nil {
http.Error(response, "upload failed", http.StatusInternalServerError) http.Error(response, "upload failed", http.StatusInternalServerError)
return return
} }
uploaded = true
}
if !uploaded {
http.Error(response, "no file in request", http.StatusBadRequest)
return
}
response.WriteHeader(http.StatusAccepted) response.WriteHeader(http.StatusAccepted)
response.Write([]byte(fileId.String()))
} }
+7 -8
View File
@@ -8,7 +8,6 @@ import (
"go-socket/packages/globals" "go-socket/packages/globals"
"github.com/google/uuid"
"github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials" "github.com/minio/minio-go/v7/pkg/credentials"
) )
@@ -65,16 +64,16 @@ func Init() {
} }
func Upload(ctx context.Context, key string, body io.Reader, size int64, contentType string, id uuid.UUID) error { func Upload(ctx context.Context, key string, body io.Reader, size int64, contentType string, metadata map[string]string) error {
_, err := minClient.PutObject(ctx, globals.FileStorageBucketName, key, body, size, opt := minio.PutObjectOptions{
minio.PutObjectOptions{
ContentType: contentType, ContentType: contentType,
PartSize: globals.FileProcessingPartSize, PartSize: globals.FileProcessingPartSize,
NumThreads: globals.FileProcessingThreads, NumThreads: globals.FileProcessingThreads,
UserMetadata: map[string]string{ UserMetadata: metadata,
"id": id.String(), }
}, opt.SetMatchETagExcept("*")
})
_, err := minClient.PutObject(ctx, globals.FileStorageBucketName, key, body, size, opt)
return err return err
} }
-77
View File
@@ -66,29 +66,6 @@ func Init(ctx context.Context) {
if err != nil { if err != nil {
panic(err) panic(err)
} }
_, err = dbConn.Exec(ctx, `
CREATE TABLE IF NOT EXISTS files_metadata (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
uploader_id UUID NOT NULL REFERENCES users(id),
name TEXT,
hash TEXT NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW()
)
`)
if err != nil {
panic(err)
}
_, err = dbConn.Exec(ctx, `
CREATE TABLE IF NOT EXISTS file_connections (
file_id UUID NOT NULL REFERENCES files_metadata(id) ON DELETE CASCADE,
connection_id UUID NOT NULL REFERENCES user_connections(id) ON DELETE CASCADE
)
`)
if err != nil {
panic(err)
}
} }
func UserSave(ctx context.Context, user *types.User) error { func UserSave(ctx context.Context, user *types.User) error {
@@ -243,57 +220,3 @@ func ConnectionGetMessagesBefore(ctx context.Context, before time.Time, connecti
} }
return messages, rows.Err() return messages, rows.Err()
} }
func FileMetadataSave(ctx context.Context, metadata *types.FileMetadata) error {
_, err := dbConn.Exec(ctx, `
INSERT INTO files_metadata (id, uploader_id, name, hash, created_at) VALUES ($1, $2, $3, $4, $5)
`, metadata.Id, metadata.UploaderId, metadata.Name, metadata.Hash, metadata.CreatedAt)
return err
}
func FileMetadataGet(ctx context.Context, metadata *types.FileMetadata) error {
return dbConn.QueryRow(ctx, `
SELECT uploader_id, name, hash, created_at FROM files_metadata WHERE id = $1
`, metadata.Id).Scan(&metadata.UploaderId, &metadata.Name, &metadata.Hash, &metadata.CreatedAt)
}
func FileMetadataDelete(ctx context.Context, metadataId *uuid.UUID) error {
_, err := dbConn.Exec(ctx, `
DELETE FROM files_metadata WHERE id = $1
`, metadataId)
return err
}
func FileConnectionsAdd(ctx context.Context, metadataId *uuid.UUID, connectionId *uuid.UUID) error {
_, err := dbConn.Exec(ctx, `
INSERT INTO file_connections (file_id, connection_id) VALUES ($1, $2)
`, metadataId, connectionId)
return err
}
func FileConnectionsGet(ctx context.Context, metadata *types.FileMetadata) error {
rows, err := dbConn.Query(ctx, `
SELECT connection_id FROM file_connections WHERE file_id = $1
`, metadata.Id)
if err != nil {
return err
}
defer rows.Close()
for rows.Next() {
connectionId := uuid.UUID{}
if err = rows.Scan(&connectionId); err != nil {
return err
}
metadata.Connections = append(metadata.Connections, connectionId)
}
return rows.Err()
}
func FileMetadataHashExists(ctx context.Context, hash *types.Sha256Hash) (bool, error) {
var exists bool
err := dbConn.QueryRow(ctx, `
SELECT EXISTS (SELECT FROM files_metadata WHERE hash = $1)
`, hash).Scan(&exists)
return exists, err
}
-9
View File
@@ -104,12 +104,3 @@ type WsAuthMessage struct {
Success bool `json:"success"` Success bool `json:"success"`
Error string `json:"error"` Error string `json:"error"`
} }
type FileMetadata struct {
CreatedAt time.Time `json:"createdAt"`
Connections []uuid.UUID `json:"connections"`
Name string `json:"name"`
Hash Sha256Hash `json:"hash"`
Id uuid.UUID `json:"id"`
UploaderId uuid.UUID `json:"uploaderId"`
}