diff --git a/modules/storage/local.go b/modules/storage/local.go index 076a7f5e2..310d1883c 100644 --- a/modules/storage/local.go +++ b/modules/storage/local.go @@ -68,3 +68,7 @@ func (l *LocalStorage) Delete(path string) error { func (l *LocalStorage) PresignedGetURL(path string, fileName string) (string,error) { return "",nil } + +func (l *LocalStorage) PresignedPutURL(path string) (string,error) { + return "",nil +} diff --git a/modules/storage/minio.go b/modules/storage/minio.go index 5fafa9965..ddbb9328b 100644 --- a/modules/storage/minio.go +++ b/modules/storage/minio.go @@ -18,7 +18,10 @@ var ( _ ObjectStorage = &MinioStorage{} ) -const PRESIGNED_URL_EXPIRE_TIME = time.Hour * 24 * 7 +const ( + PresignedGetUrlExpireTime = time.Hour * 24 * 7 + PresignedPutUrlExpireTime = time.Hour * 24 * 7 +) // MinioStorage returns a minio bucket storage type MinioStorage struct { @@ -73,14 +76,25 @@ func (m *MinioStorage) Delete(path string) error { return m.client.RemoveObject(m.bucket, m.buildMinioPath(path)) } -//Get Presigned URL +//Get Presigned URL for get object func (m *MinioStorage) PresignedGetURL(path string, fileName string) (string,error) { // Set request parameters for content-disposition. reqParams := make(url.Values) reqParams.Set("response-content-disposition", "attachment; filename=\"" + fileName + "\"") var preURL *url.URL - preURL,err := m.client.PresignedGetObject(m.bucket, m.buildMinioPath(path), PRESIGNED_URL_EXPIRE_TIME, reqParams) + preURL,err := m.client.PresignedGetObject(m.bucket, m.buildMinioPath(path), PresignedGetUrlExpireTime, reqParams) + if err != nil { + return "",err + } + + return preURL.String(),nil +} + +//Get Presigned URL for put object +func (m *MinioStorage) PresignedPutURL(path string) (string,error) { + var preURL *url.URL + preURL,err := m.client.PresignedPutObject(m.bucket, m.buildMinioPath(path), PresignedPutUrlExpireTime) if err != nil { return "",err } diff --git a/modules/storage/storage.go b/modules/storage/storage.go index 912454ac9..811315cab 100644 --- a/modules/storage/storage.go +++ b/modules/storage/storage.go @@ -22,6 +22,7 @@ type ObjectStorage interface { Open(path string) (io.ReadCloser, error) Delete(path string) error PresignedGetURL(path string, fileName string) (string, error) + PresignedPutURL(path string) (string, error) } // Copy copys a file from source ObjectStorage to dest ObjectStorage diff --git a/routers/repo/attachment.go b/routers/repo/attachment.go index 05b94ca22..5797c999c 100644 --- a/routers/repo/attachment.go +++ b/routers/repo/attachment.go @@ -15,6 +15,8 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/storage" "code.gitea.io/gitea/modules/upload" + + gouuid "github.com/satori/go.uuid" ) func RenderAttachmentSettings(ctx *context.Context) { @@ -193,3 +195,32 @@ func increaseDownloadCount(attach *models.Attachment, dataSet *models.Dataset) e return nil } + +// Get a presigned url for put object +func GetPresignedPutObjectURL(ctx *context.Context) { + if !setting.Attachment.Enabled { + ctx.Error(404, "attachment is not enabled") + return + } + + uuid := "" + url := "" + + if setting.Attachment.StoreType == storage.MinioStorageType { + uuid = gouuid.NewV4().String() + url, err := storage.Attachments.PresignedPutURL(models.AttachmentRelativePath(uuid)) + if err != nil { + ctx.ServerError("PresignedPutURL", err) + return + } + log.Trace(url) + } else { + ctx.Error(404, "storage type is not enabled") + return + } + + ctx.JSON(200, map[string]string{ + "uuid": uuid, + "url": url, + }) +} diff --git a/routers/routes/routes.go b/routers/routes/routes.go index f7d2f1d1e..9f0943deb 100644 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -519,6 +519,7 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/attachments", func() { m.Post("", repo.UploadAttachment) m.Post("/delete", repo.DeleteAttachment) + m.Get("/get_pre_url", repo.GetPresignedPutObjectURL) }, reqSignIn) m.Group("/:username", func() {