support local file as object storage

pull/74/head
alimy 3 years ago
parent 20e7d5db90
commit 46d5ef1791

@ -61,6 +61,11 @@ S3: # Amazon S3 存储配置
Endpoint: s3.amazonaws.com
Bucket: paopao
Domain:
LocalOSS: # 本地文件OSS存储配置
SavePath: data/paopao-ce/oss
Secure: False
Bucket: paopao
Domain: 127.0.0.1:8008
MySQL: # MySQL数据库
Username: paopao
Password: paopao

@ -19,6 +19,7 @@ var (
AliOSSSetting *setting.AliOSSSettingS
MinIOSetting *setting.MinIOSettingS
S3Setting *setting.S3SettingS
LocalOSSSetting *setting.LocalOSSSettingS
JWTSetting *setting.JWTSettingS
LoggerFileSetting *setting.LoggerFileSettingS
LoggerZincSetting *setting.LoggerZincSettingS

@ -84,6 +84,7 @@ func setupSetting() error {
"JWT": &global.JWTSetting,
"AliOSS": &global.AliOSSSetting,
"MinIO": &global.MinIOSetting,
"LocalOSS": &global.LocalOSSSetting,
"S3": &global.S3Setting,
}
if err = setting.Unmarshal(objects); err != nil {

@ -1,5 +1,5 @@
package core
type AttachmentCheckService interface {
Check(cUrl string) error
Check(uri string) error
}

@ -14,6 +14,7 @@ var (
_ core.ObjectStorageService = (*aliossServant)(nil)
_ core.ObjectStorageService = (*minioServant)(nil)
_ core.ObjectStorageService = (*s3Servant)(nil)
_ core.ObjectStorageService = (*localossServant)(nil)
_ core.AttachmentCheckService = (*attachmentCheckServant)(nil)
)
@ -22,6 +23,11 @@ type dataServant struct {
zinc *zinc.ZincClient
}
type localossServant struct {
savePath string
domain string
}
type aliossServant struct {
bucket *oss.Bucket
domain string
@ -56,6 +62,9 @@ func NewObjectStorageService() (oss core.ObjectStorageService) {
} else if global.CfgIf("S3") {
oss = newS3Servent()
global.Logger.Infoln("use S3 as object storage")
} else if global.CfgIf("LocalOSS") {
oss = newLocalossServent()
global.Logger.Infoln("use LocalOSS as object storage")
} else {
// default use AliOSS
oss = newAliossServent()

@ -0,0 +1,71 @@
package dao
import (
"errors"
"fmt"
"io"
"os"
"path/filepath"
"strings"
"time"
"github.com/rocboss/paopao-ce/global"
)
func newLocalossServent() *localossServant {
savePath, err := filepath.Abs(global.LocalOSSSetting.SavePath)
if err != nil {
global.Logger.Fatalf("get localOSS save path err: %v", err)
}
return &localossServant{
savePath: savePath + "/" + global.LocalOSSSetting.Bucket + "/",
domain: getOssDomain(),
}
}
func (s *localossServant) PutObject(objectKey string, reader io.Reader, objectSize int64, contentType string) (string, error) {
saveDir := s.savePath + filepath.Dir(objectKey)
err := os.MkdirAll(saveDir, 0750)
if err != nil && !os.IsExist(err) {
return "", err
}
savePath := s.savePath + objectKey
writer, err := os.Create(savePath)
if err != nil {
return "", err
}
defer writer.Close()
written, err := io.Copy(writer, reader)
if err != nil {
return "", err
}
if written != objectSize {
os.Remove(savePath)
return "", errors.New("put object not complete")
}
return s.domain + objectKey, nil
}
func (s *localossServant) SignURL(objectKey string, expiredInSec int64) (string, error) {
if expiredInSec < 0 {
return "", fmt.Errorf("invalid expires: %d, expires must bigger than 0", expiredInSec)
}
expiration := time.Now().Unix() + expiredInSec
// Fixed: Just make things simple and simple now so return an veiry simple sign url.
// Maybe make another process logic for sign url in future but not now.
uri := fmt.Sprintf("%s%s?expired=%d", s.domain, objectKey, expiration)
return uri, nil
}
func (s *localossServant) ObjectURL(objetKey string) string {
return s.domain + objetKey
}
func (s *localossServant) ObjectKey(objectUrl string) string {
return strings.Replace(objectUrl, s.domain, "", -1)
}

@ -19,6 +19,11 @@ func getOssDomain() string {
}
// TODO: will not work well need test in real world
return uri + global.S3Setting.Domain + "/" + global.S3Setting.Bucket + "/"
} else if global.CfgIf("LocalOSS") {
if !global.LocalOSSSetting.Secure {
uri = "http://"
}
return uri + global.LocalOSSSetting.Domain + "/oss/" + global.LocalOSSSetting.Bucket + "/"
}
return ""
return uri + global.AliOSSSetting.Domain + "/"
}

@ -2,9 +2,11 @@ package routers
import (
"net/http"
"path/filepath"
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/global"
"github.com/rocboss/paopao-ce/internal/middleware"
"github.com/rocboss/paopao-ce/internal/routers/api"
)
@ -21,8 +23,11 @@ func NewRouter() *gin.Engine {
corsConfig.AddAllowHeaders("Authorization")
e.Use(cors.New(corsConfig))
// 按需注册静态资源路由
// 按需注册 静态资源、LocalOSS 路由
{
registerStatick(e)
routeLocalOSS(e)
}
// v1 group api
r := e.Group("/v1")
@ -184,3 +189,18 @@ func NewRouter() *gin.Engine {
})
return e
}
// routeLocalOSS register LocalOSS route if neeed
func routeLocalOSS(e *gin.Engine) {
if !global.CfgIf("LocalOSS") {
return
}
savePath, err := filepath.Abs(global.LocalOSSSetting.SavePath)
if err != nil {
global.Logger.Fatalf("get localOSS save path err: %v", err)
}
e.Static("/oss", savePath)
global.Logger.Infof("register LocalOSS route in /oss on save path: %s", savePath)
}

@ -107,6 +107,13 @@ type AliOSSSettingS struct {
Domain string
}
type LocalOSSSettingS struct {
SavePath string
Secure bool
Bucket string
Domain string
}
type RedisSettingS struct {
Host string
Password string

@ -1,4 +1,4 @@
{
"version": "",
"buildTime": ""
"version": "3",
"buildTime": "2022-06-08 23:29:43"
}
Loading…
Cancel
Save