mirror of https://github.com/cloudreve/Cloudreve
				
				
				
			Modify: oss handle sign URL
							parent
							
								
									bd643fa2d5
								
							
						
					
					
						commit
						c4eada2723
					
				| 
						 | 
				
			
			@ -217,7 +217,9 @@ func (policy *Policy) GetUploadURL() string {
 | 
			
		|||
		return "/api/v3/file/upload"
 | 
			
		||||
	case "remote":
 | 
			
		||||
		controller, _ = url.Parse("/api/v3/slave/upload")
 | 
			
		||||
	case "oss", "cos":
 | 
			
		||||
	case "oss":
 | 
			
		||||
		return "https://" + policy.BucketName + "." + policy.Server
 | 
			
		||||
	case "cos":
 | 
			
		||||
		return policy.BaseURL
 | 
			
		||||
	case "upyun":
 | 
			
		||||
		return "http://v0.api.upyun.com/" + policy.BucketName
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,6 +49,30 @@ const (
 | 
			
		|||
	VersionID key = iota
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// CORS 创建跨域策略
 | 
			
		||||
func (handler *Driver) CORS() error {
 | 
			
		||||
	// 初始化客户端
 | 
			
		||||
	if err := handler.InitOSSClient(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return handler.client.SetBucketCORS(handler.Policy.BucketName, []oss.CORSRule{
 | 
			
		||||
		{
 | 
			
		||||
			AllowedOrigin: []string{"*"},
 | 
			
		||||
			AllowedMethod: []string{
 | 
			
		||||
				"GET",
 | 
			
		||||
				"POST",
 | 
			
		||||
				"PUT",
 | 
			
		||||
				"DELETE",
 | 
			
		||||
				"HEAD",
 | 
			
		||||
			},
 | 
			
		||||
			ExposeHeader:  []string{},
 | 
			
		||||
			AllowedHeader: []string{"*"},
 | 
			
		||||
			MaxAgeSeconds: 3600,
 | 
			
		||||
		},
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InitOSSClient 初始化OSS鉴权客户端
 | 
			
		||||
func (handler *Driver) InitOSSClient() error {
 | 
			
		||||
	if handler.Policy == nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -238,27 +262,6 @@ func (handler Driver) Source(
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func (handler Driver) signSourceURL(ctx context.Context, path string, ttl int64, options []oss.Option) (string, error) {
 | 
			
		||||
	cdnURL, err := url.Parse(handler.Policy.BaseURL)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 公有空间不需要签名
 | 
			
		||||
	if !handler.Policy.IsPrivate {
 | 
			
		||||
		file, err := url.Parse(path)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return "", err
 | 
			
		||||
		}
 | 
			
		||||
		sourceURL := cdnURL.ResolveReference(file)
 | 
			
		||||
 | 
			
		||||
		// 如果有缩略图设置
 | 
			
		||||
		if thumbSize, ok := ctx.Value(fsctx.ThumbSizeCtx).(string); ok {
 | 
			
		||||
			sourceURL.RawQuery = "x-oss-process=" + thumbSize
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return sourceURL.String(), nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	signedURL, err := handler.bucket.SignURL(path, oss.HTTPGet, ttl, options...)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
| 
						 | 
				
			
			@ -269,8 +272,26 @@ func (handler Driver) signSourceURL(ctx context.Context, path string, ttl int64,
 | 
			
		|||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
	finalURL.Host = cdnURL.Host
 | 
			
		||||
	finalURL.Scheme = cdnURL.Scheme
 | 
			
		||||
 | 
			
		||||
	// 优先使用https
 | 
			
		||||
	finalURL.Scheme = "https"
 | 
			
		||||
 | 
			
		||||
	// 公有空间替换掉Key
 | 
			
		||||
	if !handler.Policy.IsPrivate {
 | 
			
		||||
		query := finalURL.Query()
 | 
			
		||||
		query.Del("OSSAccessKeyId")
 | 
			
		||||
		query.Del("Signature")
 | 
			
		||||
		finalURL.RawQuery = query.Encode()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if handler.Policy.BaseURL != "" {
 | 
			
		||||
		cdnURL, err := url.Parse(handler.Policy.BaseURL)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return "", err
 | 
			
		||||
		}
 | 
			
		||||
		finalURL.Host = cdnURL.Host
 | 
			
		||||
		finalURL.Scheme = cdnURL.Scheme
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return finalURL.String(), nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -301,10 +322,14 @@ func (handler Driver) Token(ctx context.Context, TTL int64, key string) (seriali
 | 
			
		|||
		Conditions: []interface{}{
 | 
			
		||||
			map[string]string{"bucket": handler.Policy.BucketName},
 | 
			
		||||
			[]string{"starts-with", "$key", path.Dir(savePath)},
 | 
			
		||||
			[]interface{}{"content-length-range", 0, handler.Policy.MaxSize},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if handler.Policy.MaxSize > 0 {
 | 
			
		||||
		postPolicy.Conditions = append(postPolicy.Conditions,
 | 
			
		||||
			[]interface{}{"content-length-range", 0, handler.Policy.MaxSize})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return handler.getUploadCredential(ctx, postPolicy, callbackPolicy, TTL)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -154,7 +154,7 @@ func (fs *FileSystem) GetUploadToken(ctx context.Context, path string, size uint
 | 
			
		|||
	// 是否需要预先生成存储路径
 | 
			
		||||
	var savePath string
 | 
			
		||||
	if fs.User.Policy.IsPathGenerateNeeded() {
 | 
			
		||||
		savePath = fs.GenerateSavePath(ctx, local.FileStream{Name: name})
 | 
			
		||||
		savePath = fs.GenerateSavePath(ctx, local.FileStream{Name: name, VirtualPath: path})
 | 
			
		||||
		ctx = context.WithValue(ctx, fsctx.SavePathCtx, savePath)
 | 
			
		||||
	}
 | 
			
		||||
	ctx = context.WithValue(ctx, fsctx.FileSizeCtx, size)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -172,3 +172,14 @@ func AdminAddPolicy(c *gin.Context) {
 | 
			
		|||
		c.JSON(200, ErrorResponse(err))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AdminAddCORS 创建跨域策略
 | 
			
		||||
func AdminAddCORS(c *gin.Context) {
 | 
			
		||||
	var service admin.PolicyService
 | 
			
		||||
	if err := c.ShouldBindJSON(&service); err == nil {
 | 
			
		||||
		res := service.AddCORS()
 | 
			
		||||
		c.JSON(200, res)
 | 
			
		||||
	} else {
 | 
			
		||||
		c.JSON(200, ErrorResponse(err))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -334,6 +334,8 @@ func InitMasterRouter() *gin.Engine {
 | 
			
		|||
					policy.POST("test/slave", controllers.AdminTestSlave)
 | 
			
		||||
					// 创建存储策略
 | 
			
		||||
					policy.POST("", controllers.AdminAddPolicy)
 | 
			
		||||
					// 创建存储策略
 | 
			
		||||
					policy.POST("cors", controllers.AdminAddCORS)
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ import (
 | 
			
		|||
	model "github.com/HFO4/cloudreve/models"
 | 
			
		||||
	"github.com/HFO4/cloudreve/pkg/auth"
 | 
			
		||||
	"github.com/HFO4/cloudreve/pkg/conf"
 | 
			
		||||
	"github.com/HFO4/cloudreve/pkg/filesystem/driver/oss"
 | 
			
		||||
	"github.com/HFO4/cloudreve/pkg/request"
 | 
			
		||||
	"github.com/HFO4/cloudreve/pkg/serializer"
 | 
			
		||||
	"github.com/HFO4/cloudreve/pkg/util"
 | 
			
		||||
| 
						 | 
				
			
			@ -37,6 +38,34 @@ type AddPolicyService struct {
 | 
			
		|||
	Policy model.Policy `json:"policy" binding:"required"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PolicyService 存储策略ID服务
 | 
			
		||||
type PolicyService struct {
 | 
			
		||||
	ID uint `json:"id" binding:"required"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddCORS 创建跨域策略
 | 
			
		||||
func (service *PolicyService) AddCORS() serializer.Response {
 | 
			
		||||
	policy, err := model.GetPolicyByID(service.ID)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return serializer.Err(serializer.CodeNotFound, "存储策略不存在", nil)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch policy.Type {
 | 
			
		||||
	case "oss":
 | 
			
		||||
		handler := oss.Driver{
 | 
			
		||||
			Policy:     &policy,
 | 
			
		||||
			HTTPClient: request.HTTPClient{},
 | 
			
		||||
		}
 | 
			
		||||
		if err := handler.CORS(); err != nil {
 | 
			
		||||
			return serializer.Err(serializer.CodeInternalSetting, "跨域策略添加失败", err)
 | 
			
		||||
		}
 | 
			
		||||
	default:
 | 
			
		||||
		return serializer.ParamErr("不支持此策略", nil)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return serializer.Response{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Test 从机响应ping
 | 
			
		||||
func (service *SlavePingService) Test() serializer.Response {
 | 
			
		||||
	master, err := url.Parse(service.Callback)
 | 
			
		||||
| 
						 | 
				
			
			@ -107,7 +136,7 @@ func (service *AddPolicyService) Add() serializer.Response {
 | 
			
		|||
	if err := model.DB.Create(&service.Policy).Error; err != nil {
 | 
			
		||||
		return serializer.ParamErr("存储策略添加失败", err)
 | 
			
		||||
	}
 | 
			
		||||
	return serializer.Response{}
 | 
			
		||||
	return serializer.Response{Data: service.Policy.ID}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Test 测试本地路径
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue