Test: oss driver
This commit is contained in:
parent
83a17645a1
commit
3da87ba7cf
12 changed files with 348 additions and 71 deletions
|
@ -173,6 +173,12 @@ func TestPolicy_GetUploadURL(t *testing.T) {
|
|||
asserts.Equal("http://127.0.0.1/api/v3/slave/upload", policy.GetUploadURL())
|
||||
}
|
||||
|
||||
// OSS
|
||||
{
|
||||
policy := Policy{Type: "oss", BaseURL: "base", Server: "http://127.0.0.1"}
|
||||
asserts.Equal("base", policy.GetUploadURL())
|
||||
}
|
||||
|
||||
// 未知
|
||||
{
|
||||
policy := Policy{Type: "unknown", Server: "http://127.0.0.1"}
|
||||
|
|
|
@ -35,7 +35,7 @@ type FileHeader interface {
|
|||
GetVirtualPath() string
|
||||
}
|
||||
|
||||
// Handler 存储策略适配器
|
||||
// Driver 存储策略适配器
|
||||
type Handler interface {
|
||||
// 上传文件, dst为文件存储路径,size 为文件大小。上下文关闭
|
||||
// 时,应取消上传并清理临时文件
|
||||
|
@ -128,7 +128,7 @@ func NewAnonymousFileSystem() (*FileSystem, error) {
|
|||
fs.User.Group = anonymousGroup
|
||||
} else {
|
||||
// 从机模式下,分配本地策略处理器
|
||||
fs.Handler = local.Handler{}
|
||||
fs.Handler = local.Driver{}
|
||||
}
|
||||
|
||||
return fs, nil
|
||||
|
@ -153,25 +153,26 @@ func (fs *FileSystem) dispatchHandler() error {
|
|||
case "mock":
|
||||
return nil
|
||||
case "local":
|
||||
fs.Handler = local.Handler{
|
||||
fs.Handler = local.Driver{
|
||||
Policy: currentPolicy,
|
||||
}
|
||||
return nil
|
||||
case "remote":
|
||||
fs.Handler = remote.Handler{
|
||||
fs.Handler = remote.Driver{
|
||||
Policy: currentPolicy,
|
||||
Client: request.HTTPClient{},
|
||||
AuthInstance: auth.HMACAuth{[]byte(currentPolicy.SecretKey)},
|
||||
}
|
||||
return nil
|
||||
case "qiniu":
|
||||
fs.Handler = qiniu.Handler{
|
||||
fs.Handler = qiniu.Driver{
|
||||
Policy: currentPolicy,
|
||||
}
|
||||
return nil
|
||||
case "oss":
|
||||
fs.Handler = oss.Handler{
|
||||
Policy: currentPolicy,
|
||||
fs.Handler = oss.Driver{
|
||||
Policy: currentPolicy,
|
||||
HTTPClient: request.HTTPClient{},
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
|
|
|
@ -24,13 +24,13 @@ func TestNewFileSystem(t *testing.T) {
|
|||
fs, err := NewFileSystem(&user)
|
||||
asserts.NoError(err)
|
||||
asserts.NotNil(fs.Handler)
|
||||
asserts.IsType(local.Handler{}, fs.Handler)
|
||||
asserts.IsType(local.Driver{}, fs.Handler)
|
||||
// 远程
|
||||
user.Policy.Type = "remote"
|
||||
fs, err = NewFileSystem(&user)
|
||||
asserts.NoError(err)
|
||||
asserts.NotNil(fs.Handler)
|
||||
asserts.IsType(remote.Handler{}, fs.Handler)
|
||||
asserts.IsType(remote.Driver{}, fs.Handler)
|
||||
|
||||
user.Policy.Type = "unknown"
|
||||
fs, err = NewFileSystem(&user)
|
||||
|
@ -66,7 +66,7 @@ func TestDispatchHandler(t *testing.T) {
|
|||
// 未指定,使用用户默认
|
||||
err := fs.dispatchHandler()
|
||||
asserts.NoError(err)
|
||||
asserts.IsType(local.Handler{}, fs.Handler)
|
||||
asserts.IsType(local.Driver{}, fs.Handler)
|
||||
|
||||
// 已指定,发生错误
|
||||
fs.Policy = &model.Policy{Type: "unknown"}
|
||||
|
|
|
@ -74,7 +74,7 @@ func TestGenericAfterUploadCanceled(t *testing.T) {
|
|||
ctx = context.WithValue(ctx, fsctx.FileHeaderCtx, file)
|
||||
fs := FileSystem{
|
||||
User: &model.User{Storage: 5},
|
||||
Handler: local.Handler{},
|
||||
Handler: local.Driver{},
|
||||
}
|
||||
|
||||
// 成功
|
||||
|
|
|
@ -18,13 +18,13 @@ import (
|
|||
"path/filepath"
|
||||
)
|
||||
|
||||
// Handler 本地策略适配器
|
||||
type Handler struct {
|
||||
// Driver 本地策略适配器
|
||||
type Driver struct {
|
||||
Policy *model.Policy
|
||||
}
|
||||
|
||||
// Get 获取文件内容
|
||||
func (handler Handler) Get(ctx context.Context, path string) (response.RSCloser, error) {
|
||||
func (handler Driver) Get(ctx context.Context, path string) (response.RSCloser, error) {
|
||||
// 打开文件
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
|
@ -49,7 +49,7 @@ func closeReader(ctx context.Context, closer io.Closer) {
|
|||
}
|
||||
|
||||
// Put 将文件流保存到指定目录
|
||||
func (handler Handler) Put(ctx context.Context, file io.ReadCloser, dst string, size uint64) error {
|
||||
func (handler Driver) Put(ctx context.Context, file io.ReadCloser, dst string, size uint64) error {
|
||||
defer file.Close()
|
||||
dst = filepath.FromSlash(dst)
|
||||
|
||||
|
@ -78,7 +78,7 @@ func (handler Handler) Put(ctx context.Context, file io.ReadCloser, dst string,
|
|||
|
||||
// Delete 删除一个或多个文件,
|
||||
// 返回未删除的文件,及遇到的最后一个错误
|
||||
func (handler Handler) Delete(ctx context.Context, files []string) ([]string, error) {
|
||||
func (handler Driver) Delete(ctx context.Context, files []string) ([]string, error) {
|
||||
deleteFailed := make([]string, 0, len(files))
|
||||
var retErr error
|
||||
|
||||
|
@ -98,7 +98,7 @@ func (handler Handler) Delete(ctx context.Context, files []string) ([]string, er
|
|||
}
|
||||
|
||||
// Thumb 获取文件缩略图
|
||||
func (handler Handler) Thumb(ctx context.Context, path string) (*response.ContentResponse, error) {
|
||||
func (handler Driver) Thumb(ctx context.Context, path string) (*response.ContentResponse, error) {
|
||||
file, err := handler.Get(ctx, path+conf.ThumbConfig.FileSuffix)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -111,7 +111,7 @@ func (handler Handler) Thumb(ctx context.Context, path string) (*response.Conten
|
|||
}
|
||||
|
||||
// Source 获取外链URL
|
||||
func (handler Handler) Source(
|
||||
func (handler Driver) Source(
|
||||
ctx context.Context,
|
||||
path string,
|
||||
baseURL url.URL,
|
||||
|
@ -160,6 +160,6 @@ func (handler Handler) Source(
|
|||
}
|
||||
|
||||
// Token 获取上传策略和认证Token,本地策略直接返回空值
|
||||
func (handler Handler) Token(ctx context.Context, ttl int64, key string) (serializer.UploadCredential, error) {
|
||||
func (handler Driver) Token(ctx context.Context, ttl int64, key string) (serializer.UploadCredential, error) {
|
||||
return serializer.UploadCredential{}, nil
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
|
||||
func TestHandler_Put(t *testing.T) {
|
||||
asserts := assert.New(t)
|
||||
handler := Handler{}
|
||||
handler := Driver{}
|
||||
ctx := context.Background()
|
||||
|
||||
testCases := []struct {
|
||||
|
@ -52,7 +52,7 @@ func TestHandler_Put(t *testing.T) {
|
|||
|
||||
func TestHandler_Delete(t *testing.T) {
|
||||
asserts := assert.New(t)
|
||||
handler := Handler{}
|
||||
handler := Driver{}
|
||||
ctx := context.Background()
|
||||
|
||||
file, err := os.Create("test.file")
|
||||
|
@ -76,7 +76,7 @@ func TestHandler_Delete(t *testing.T) {
|
|||
|
||||
func TestHandler_Get(t *testing.T) {
|
||||
asserts := assert.New(t)
|
||||
handler := Handler{}
|
||||
handler := Driver{}
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
|
@ -98,7 +98,7 @@ func TestHandler_Get(t *testing.T) {
|
|||
|
||||
func TestHandler_Thumb(t *testing.T) {
|
||||
asserts := assert.New(t)
|
||||
handler := Handler{}
|
||||
handler := Driver{}
|
||||
ctx := context.Background()
|
||||
file, err := os.Create("TestHandler_Thumb" + conf.ThumbConfig.FileSuffix)
|
||||
asserts.NoError(err)
|
||||
|
@ -120,7 +120,7 @@ func TestHandler_Thumb(t *testing.T) {
|
|||
|
||||
func TestHandler_Source(t *testing.T) {
|
||||
asserts := assert.New(t)
|
||||
handler := Handler{}
|
||||
handler := Driver{}
|
||||
ctx := context.Background()
|
||||
auth.General = auth.HMACAuth{SecretKey: []byte("test")}
|
||||
|
||||
|
@ -154,7 +154,7 @@ func TestHandler_Source(t *testing.T) {
|
|||
|
||||
func TestHandler_GetDownloadURL(t *testing.T) {
|
||||
asserts := assert.New(t)
|
||||
handler := Handler{}
|
||||
handler := Driver{}
|
||||
ctx := context.Background()
|
||||
auth.General = auth.HMACAuth{SecretKey: []byte("test")}
|
||||
|
||||
|
@ -187,7 +187,7 @@ func TestHandler_GetDownloadURL(t *testing.T) {
|
|||
|
||||
func TestHandler_Token(t *testing.T) {
|
||||
asserts := assert.New(t)
|
||||
handler := Handler{}
|
||||
handler := Driver{}
|
||||
ctx := context.Background()
|
||||
_, err := handler.Token(ctx, 10, "123")
|
||||
asserts.NoError(err)
|
||||
|
|
270
pkg/filesystem/oss/handler_test.go
Normal file
270
pkg/filesystem/oss/handler_test.go
Normal file
|
@ -0,0 +1,270 @@
|
|||
package oss
|
||||
|
||||
import (
|
||||
"context"
|
||||
model "github.com/HFO4/cloudreve/models"
|
||||
"github.com/HFO4/cloudreve/pkg/cache"
|
||||
"github.com/HFO4/cloudreve/pkg/filesystem/fsctx"
|
||||
"github.com/HFO4/cloudreve/pkg/request"
|
||||
"github.com/stretchr/testify/assert"
|
||||
testMock "github.com/stretchr/testify/mock"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDriver_InitOSSClient(t *testing.T) {
|
||||
asserts := assert.New(t)
|
||||
handler := Driver{
|
||||
Policy: &model.Policy{
|
||||
AccessKey: "ak",
|
||||
SecretKey: "sk",
|
||||
BucketName: "test",
|
||||
Server: "test.com",
|
||||
},
|
||||
}
|
||||
|
||||
// 成功
|
||||
{
|
||||
asserts.NoError(handler.InitOSSClient())
|
||||
}
|
||||
|
||||
// 未指定存储策略
|
||||
{
|
||||
handler := Driver{}
|
||||
asserts.Error(handler.InitOSSClient())
|
||||
}
|
||||
}
|
||||
|
||||
func TestDriver_Token(t *testing.T) {
|
||||
asserts := assert.New(t)
|
||||
handler := Driver{
|
||||
Policy: &model.Policy{
|
||||
AccessKey: "ak",
|
||||
SecretKey: "sk",
|
||||
BucketName: "test",
|
||||
Server: "test.com",
|
||||
},
|
||||
}
|
||||
|
||||
// 成功
|
||||
{
|
||||
ctx := context.WithValue(context.Background(), fsctx.SavePathCtx, "/123")
|
||||
cache.Set("setting_siteURL", "http://test.cloudreve.org", 0)
|
||||
res, err := handler.Token(ctx, 10, "key")
|
||||
asserts.NoError(err)
|
||||
asserts.NotEmpty(res.Policy)
|
||||
asserts.NotEmpty(res.Token)
|
||||
asserts.Equal(handler.Policy.AccessKey, res.AccessKey)
|
||||
asserts.Equal("/123", res.Path)
|
||||
}
|
||||
|
||||
// 上下文错误
|
||||
{
|
||||
ctx := context.Background()
|
||||
_, err := handler.Token(ctx, 10, "key")
|
||||
asserts.Error(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestDriver_Source(t *testing.T) {
|
||||
asserts := assert.New(t)
|
||||
handler := Driver{
|
||||
Policy: &model.Policy{
|
||||
AccessKey: "ak",
|
||||
SecretKey: "sk",
|
||||
BucketName: "test",
|
||||
Server: "test.com",
|
||||
},
|
||||
}
|
||||
|
||||
// 正常 非下载 无限速
|
||||
{
|
||||
res, err := handler.Source(context.Background(), "/123", url.URL{}, 10, false, 0)
|
||||
asserts.NoError(err)
|
||||
resURL, err := url.Parse(res)
|
||||
asserts.NoError(err)
|
||||
query := resURL.Query()
|
||||
asserts.NotEmpty(query.Get("Signature"))
|
||||
asserts.NotEmpty(query.Get("Expires"))
|
||||
asserts.Equal("ak", query.Get("OSSAccessKeyId"))
|
||||
}
|
||||
|
||||
// 限速 + 下载
|
||||
{
|
||||
ctx := context.WithValue(context.Background(), fsctx.FileModelCtx, model.File{Name: "123.txt"})
|
||||
res, err := handler.Source(ctx, "/123", url.URL{}, 10, true, 819201)
|
||||
asserts.NoError(err)
|
||||
resURL, err := url.Parse(res)
|
||||
asserts.NoError(err)
|
||||
query := resURL.Query()
|
||||
asserts.NotEmpty(query.Get("Signature"))
|
||||
asserts.NotEmpty(query.Get("Expires"))
|
||||
asserts.Equal("ak", query.Get("OSSAccessKeyId"))
|
||||
asserts.EqualValues("819201", query.Get("x-oss-traffic-limit"))
|
||||
asserts.NotEmpty(query.Get("response-content-disposition"))
|
||||
}
|
||||
|
||||
// 限速超出范围 + 下载
|
||||
{
|
||||
ctx := context.WithValue(context.Background(), fsctx.FileModelCtx, model.File{Name: "123.txt"})
|
||||
res, err := handler.Source(ctx, "/123", url.URL{}, 10, true, 10)
|
||||
asserts.NoError(err)
|
||||
resURL, err := url.Parse(res)
|
||||
asserts.NoError(err)
|
||||
query := resURL.Query()
|
||||
asserts.NotEmpty(query.Get("Signature"))
|
||||
asserts.NotEmpty(query.Get("Expires"))
|
||||
asserts.Equal("ak", query.Get("OSSAccessKeyId"))
|
||||
asserts.EqualValues("819200", query.Get("x-oss-traffic-limit"))
|
||||
asserts.NotEmpty(query.Get("response-content-disposition"))
|
||||
}
|
||||
|
||||
// 限速超出范围 + 下载
|
||||
{
|
||||
ctx := context.WithValue(context.Background(), fsctx.FileModelCtx, model.File{Name: "123.txt"})
|
||||
res, err := handler.Source(ctx, "/123", url.URL{}, 10, true, 838860801)
|
||||
asserts.NoError(err)
|
||||
resURL, err := url.Parse(res)
|
||||
asserts.NoError(err)
|
||||
query := resURL.Query()
|
||||
asserts.NotEmpty(query.Get("Signature"))
|
||||
asserts.NotEmpty(query.Get("Expires"))
|
||||
asserts.Equal("ak", query.Get("OSSAccessKeyId"))
|
||||
asserts.EqualValues("838860800", query.Get("x-oss-traffic-limit"))
|
||||
asserts.NotEmpty(query.Get("response-content-disposition"))
|
||||
}
|
||||
}
|
||||
|
||||
func TestDriver_Thumb(t *testing.T) {
|
||||
asserts := assert.New(t)
|
||||
handler := Driver{
|
||||
Policy: &model.Policy{
|
||||
AccessKey: "ak",
|
||||
SecretKey: "sk",
|
||||
BucketName: "test",
|
||||
Server: "test.com",
|
||||
},
|
||||
}
|
||||
|
||||
// 上下文不存在
|
||||
{
|
||||
ctx := context.Background()
|
||||
res, err := handler.Thumb(ctx, "/123.txt")
|
||||
asserts.Error(err)
|
||||
asserts.Nil(res)
|
||||
}
|
||||
|
||||
// 成功
|
||||
{
|
||||
cache.Set("setting_preview_timeout", "60", 0)
|
||||
ctx := context.WithValue(context.Background(), fsctx.ThumbSizeCtx, [2]uint{10, 20})
|
||||
res, err := handler.Thumb(ctx, "/123.jpg")
|
||||
asserts.NoError(err)
|
||||
resURL, err := url.Parse(res.URL)
|
||||
asserts.NoError(err)
|
||||
urlQuery := resURL.Query()
|
||||
asserts.Equal("image/resize,m_lfit,h_20,w_10", urlQuery.Get("x-oss-process"))
|
||||
}
|
||||
}
|
||||
|
||||
func TestDriver_Delete(t *testing.T) {
|
||||
asserts := assert.New(t)
|
||||
handler := Driver{
|
||||
Policy: &model.Policy{
|
||||
AccessKey: "ak",
|
||||
SecretKey: "sk",
|
||||
BucketName: "test",
|
||||
Server: "oss-cn-shanghai.aliyuncs.com",
|
||||
},
|
||||
}
|
||||
|
||||
// 失败
|
||||
{
|
||||
res, err := handler.Delete(context.Background(), []string{"1", "2", "3"})
|
||||
asserts.Error(err)
|
||||
asserts.Equal([]string{"1", "2", "3"}, res)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDriver_Put(t *testing.T) {
|
||||
asserts := assert.New(t)
|
||||
handler := Driver{
|
||||
Policy: &model.Policy{
|
||||
AccessKey: "ak",
|
||||
SecretKey: "sk",
|
||||
BucketName: "test",
|
||||
Server: "oss-cn-shanghai.aliyuncs.com",
|
||||
},
|
||||
}
|
||||
cache.Set("setting_upload_credential_timeout", "3600", 0)
|
||||
|
||||
// 失败
|
||||
{
|
||||
err := handler.Put(context.Background(), ioutil.NopCloser(strings.NewReader("123")), "/123.txt", 3)
|
||||
asserts.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
type ClientMock struct {
|
||||
testMock.Mock
|
||||
}
|
||||
|
||||
func (m ClientMock) Request(method, target string, body io.Reader, opts ...request.Option) *request.Response {
|
||||
args := m.Called(method, target, body, opts)
|
||||
return args.Get(0).(*request.Response)
|
||||
}
|
||||
|
||||
func TestDriver_Get(t *testing.T) {
|
||||
asserts := assert.New(t)
|
||||
handler := Driver{
|
||||
Policy: &model.Policy{
|
||||
AccessKey: "ak",
|
||||
SecretKey: "sk",
|
||||
BucketName: "test",
|
||||
Server: "oss-cn-shanghai.aliyuncs.com",
|
||||
},
|
||||
HTTPClient: request.HTTPClient{},
|
||||
}
|
||||
cache.Set("setting_preview_timeout", "3600", 0)
|
||||
|
||||
// 响应失败
|
||||
{
|
||||
res, err := handler.Get(context.Background(), "123.txt")
|
||||
asserts.Error(err)
|
||||
asserts.Nil(res)
|
||||
}
|
||||
|
||||
// 响应成功
|
||||
{
|
||||
ctx := context.WithValue(context.Background(), fsctx.FileModelCtx, model.File{Size: 3})
|
||||
clientMock := ClientMock{}
|
||||
clientMock.On(
|
||||
"Request",
|
||||
"GET",
|
||||
testMock.Anything,
|
||||
testMock.Anything,
|
||||
testMock.Anything,
|
||||
).Return(&request.Response{
|
||||
Err: nil,
|
||||
Response: &http.Response{
|
||||
StatusCode: 200,
|
||||
Body: ioutil.NopCloser(strings.NewReader(`123`)),
|
||||
},
|
||||
})
|
||||
handler.HTTPClient = clientMock
|
||||
res, err := handler.Get(ctx, "123.txt")
|
||||
clientMock.AssertExpectations(t)
|
||||
asserts.NoError(err)
|
||||
n, err := res.Seek(0, io.SeekEnd)
|
||||
asserts.NoError(err)
|
||||
asserts.EqualValues(3, n)
|
||||
content, err := ioutil.ReadAll(res)
|
||||
asserts.NoError(err)
|
||||
asserts.Equal("123", string(content))
|
||||
}
|
||||
}
|
|
@ -34,11 +34,12 @@ type CallbackPolicy struct {
|
|||
CallbackBodyType string `json:"callbackBodyType"`
|
||||
}
|
||||
|
||||
// Handler 阿里云OSS策略适配器
|
||||
type Handler struct {
|
||||
Policy *model.Policy
|
||||
client *oss.Client
|
||||
bucket *oss.Bucket
|
||||
// Driver 阿里云OSS策略适配器
|
||||
type Driver struct {
|
||||
Policy *model.Policy
|
||||
client *oss.Client
|
||||
bucket *oss.Bucket
|
||||
HTTPClient request.Client
|
||||
}
|
||||
|
||||
type key int
|
||||
|
@ -49,7 +50,7 @@ const (
|
|||
)
|
||||
|
||||
// InitOSSClient 初始化OSS鉴权客户端
|
||||
func (handler *Handler) InitOSSClient() error {
|
||||
func (handler *Driver) InitOSSClient() error {
|
||||
if handler.Policy == nil {
|
||||
return errors.New("存储策略为空")
|
||||
}
|
||||
|
@ -75,7 +76,7 @@ func (handler *Handler) InitOSSClient() error {
|
|||
}
|
||||
|
||||
// Get 获取文件
|
||||
func (handler Handler) Get(ctx context.Context, path string) (response.RSCloser, error) {
|
||||
func (handler Driver) Get(ctx context.Context, path string) (response.RSCloser, error) {
|
||||
// 通过VersionID禁止缓存
|
||||
ctx = context.WithValue(ctx, VersionID, time.Now().UnixNano())
|
||||
|
||||
|
@ -93,8 +94,7 @@ func (handler Handler) Get(ctx context.Context, path string) (response.RSCloser,
|
|||
}
|
||||
|
||||
// 获取文件数据流
|
||||
client := request.HTTPClient{}
|
||||
resp, err := client.Request(
|
||||
resp, err := handler.HTTPClient.Request(
|
||||
"GET",
|
||||
downloadURL,
|
||||
nil,
|
||||
|
@ -115,7 +115,7 @@ func (handler Handler) Get(ctx context.Context, path string) (response.RSCloser,
|
|||
}
|
||||
|
||||
// Put 将文件流保存到指定目录
|
||||
func (handler Handler) Put(ctx context.Context, file io.ReadCloser, dst string, size uint64) error {
|
||||
func (handler Driver) Put(ctx context.Context, file io.ReadCloser, dst string, size uint64) error {
|
||||
defer file.Close()
|
||||
|
||||
// 初始化客户端
|
||||
|
@ -141,7 +141,7 @@ func (handler Handler) Put(ctx context.Context, file io.ReadCloser, dst string,
|
|||
|
||||
// Delete 删除一个或多个文件,
|
||||
// 返回未删除的文件
|
||||
func (handler Handler) Delete(ctx context.Context, files []string) ([]string, error) {
|
||||
func (handler Driver) Delete(ctx context.Context, files []string) ([]string, error) {
|
||||
// 初始化客户端
|
||||
if err := handler.InitOSSClient(); err != nil {
|
||||
return files, err
|
||||
|
@ -164,7 +164,7 @@ func (handler Handler) Delete(ctx context.Context, files []string) ([]string, er
|
|||
}
|
||||
|
||||
// Thumb 获取文件缩略图
|
||||
func (handler Handler) Thumb(ctx context.Context, path string) (*response.ContentResponse, error) {
|
||||
func (handler Driver) Thumb(ctx context.Context, path string) (*response.ContentResponse, error) {
|
||||
// 初始化客户端
|
||||
if err := handler.InitOSSClient(); err != nil {
|
||||
return nil, err
|
||||
|
@ -197,7 +197,7 @@ func (handler Handler) Thumb(ctx context.Context, path string) (*response.Conten
|
|||
}
|
||||
|
||||
// Source 获取外链URL
|
||||
func (handler Handler) Source(
|
||||
func (handler Driver) Source(
|
||||
ctx context.Context,
|
||||
path string,
|
||||
baseURL url.URL,
|
||||
|
@ -235,7 +235,7 @@ func (handler Handler) Source(
|
|||
return handler.signSourceURL(ctx, path, ttl, signOptions)
|
||||
}
|
||||
|
||||
func (handler Handler) signSourceURL(ctx context.Context, path string, ttl int64, options []oss.Option) (string, error) {
|
||||
func (handler Driver) signSourceURL(ctx context.Context, path string, ttl int64, options []oss.Option) (string, error) {
|
||||
// 是否带有 Version ID
|
||||
if _, ok := ctx.Value(VersionID).(int64); ok {
|
||||
|
||||
|
@ -261,7 +261,7 @@ func (handler Handler) signSourceURL(ctx context.Context, path string, ttl int64
|
|||
}
|
||||
|
||||
// Token 获取上传策略和认证Token
|
||||
func (handler Handler) Token(ctx context.Context, TTL int64, key string) (serializer.UploadCredential, error) {
|
||||
func (handler Driver) Token(ctx context.Context, TTL int64, key string) (serializer.UploadCredential, error) {
|
||||
// 读取上下文中生成的存储路径
|
||||
savePath, ok := ctx.Value(fsctx.SavePathCtx).(string)
|
||||
if !ok {
|
||||
|
@ -293,7 +293,7 @@ func (handler Handler) Token(ctx context.Context, TTL int64, key string) (serial
|
|||
return handler.getUploadCredential(ctx, postPolicy, callbackPolicy, TTL)
|
||||
}
|
||||
|
||||
func (handler Handler) getUploadCredential(ctx context.Context, policy UploadPolicy, callback CallbackPolicy, TTL int64) (serializer.UploadCredential, error) {
|
||||
func (handler Driver) getUploadCredential(ctx context.Context, policy UploadPolicy, callback CallbackPolicy, TTL int64) (serializer.UploadCredential, error) {
|
||||
// 读取上下文中生成的存储路径
|
||||
savePath, ok := ctx.Value(fsctx.SavePathCtx).(string)
|
||||
if !ok {
|
||||
|
|
|
@ -17,13 +17,13 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// Handler 本地策略适配器
|
||||
type Handler struct {
|
||||
// Driver 本地策略适配器
|
||||
type Driver struct {
|
||||
Policy *model.Policy
|
||||
}
|
||||
|
||||
// Get 获取文件
|
||||
func (handler Handler) Get(ctx context.Context, path string) (response.RSCloser, error) {
|
||||
func (handler Driver) Get(ctx context.Context, path string) (response.RSCloser, error) {
|
||||
// 给文件名加上随机参数以强制拉取
|
||||
path = fmt.Sprintf("%s?v=%d", path, time.Now().UnixNano())
|
||||
|
||||
|
@ -66,7 +66,7 @@ func (handler Handler) Get(ctx context.Context, path string) (response.RSCloser,
|
|||
}
|
||||
|
||||
// Put 将文件流保存到指定目录
|
||||
func (handler Handler) Put(ctx context.Context, file io.ReadCloser, dst string, size uint64) error {
|
||||
func (handler Driver) Put(ctx context.Context, file io.ReadCloser, dst string, size uint64) error {
|
||||
defer file.Close()
|
||||
|
||||
// 凭证有效期
|
||||
|
@ -110,7 +110,7 @@ func (handler Handler) Put(ctx context.Context, file io.ReadCloser, dst string,
|
|||
|
||||
// Delete 删除一个或多个文件,
|
||||
// 返回未删除的文件
|
||||
func (handler Handler) Delete(ctx context.Context, files []string) ([]string, error) {
|
||||
func (handler Driver) Delete(ctx context.Context, files []string) ([]string, error) {
|
||||
// TODO 大于一千个文件需要分批发送
|
||||
deleteOps := make([]string, 0, len(files))
|
||||
for _, key := range files {
|
||||
|
@ -139,7 +139,7 @@ func (handler Handler) Delete(ctx context.Context, files []string) ([]string, er
|
|||
}
|
||||
|
||||
// Thumb 获取文件缩略图
|
||||
func (handler Handler) Thumb(ctx context.Context, path string) (*response.ContentResponse, error) {
|
||||
func (handler Driver) Thumb(ctx context.Context, path string) (*response.ContentResponse, error) {
|
||||
var (
|
||||
thumbSize = [2]uint{400, 300}
|
||||
ok = false
|
||||
|
@ -160,7 +160,7 @@ func (handler Handler) Thumb(ctx context.Context, path string) (*response.Conten
|
|||
}
|
||||
|
||||
// Source 获取外链URL
|
||||
func (handler Handler) Source(
|
||||
func (handler Driver) Source(
|
||||
ctx context.Context,
|
||||
path string,
|
||||
baseURL url.URL,
|
||||
|
@ -183,7 +183,7 @@ func (handler Handler) Source(
|
|||
return handler.signSourceURL(ctx, path, ttl), nil
|
||||
}
|
||||
|
||||
func (handler Handler) signSourceURL(ctx context.Context, path string, ttl int64) string {
|
||||
func (handler Driver) signSourceURL(ctx context.Context, path string, ttl int64) string {
|
||||
var sourceURL string
|
||||
if handler.Policy.IsPrivate {
|
||||
mac := qbox.NewMac(handler.Policy.AccessKey, handler.Policy.SecretKey)
|
||||
|
@ -196,7 +196,7 @@ func (handler Handler) signSourceURL(ctx context.Context, path string, ttl int64
|
|||
}
|
||||
|
||||
// Token 获取上传策略和认证Token
|
||||
func (handler Handler) Token(ctx context.Context, TTL int64, key string) (serializer.UploadCredential, error) {
|
||||
func (handler Driver) Token(ctx context.Context, TTL int64, key string) (serializer.UploadCredential, error) {
|
||||
// 生成回调地址
|
||||
siteURL := model.GetSiteURL()
|
||||
apiBaseURI, _ := url.Parse("/api/v3/callback/qiniu/" + key)
|
||||
|
@ -227,7 +227,7 @@ func (handler Handler) Token(ctx context.Context, TTL int64, key string) (serial
|
|||
}
|
||||
|
||||
// getUploadCredential 签名上传策略
|
||||
func (handler Handler) getUploadCredential(ctx context.Context, policy storage.PutPolicy, TTL int64) (serializer.UploadCredential, error) {
|
||||
func (handler Driver) getUploadCredential(ctx context.Context, policy storage.PutPolicy, TTL int64) (serializer.UploadCredential, error) {
|
||||
policy.Expires = uint64(TTL)
|
||||
mac := qbox.NewMac(handler.Policy.AccessKey, handler.Policy.SecretKey)
|
||||
upToken := policy.UploadToken(mac)
|
||||
|
|
|
@ -19,15 +19,15 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
// Handler 远程存储策略适配器
|
||||
type Handler struct {
|
||||
// Driver 远程存储策略适配器
|
||||
type Driver struct {
|
||||
Client request.Client
|
||||
Policy *model.Policy
|
||||
AuthInstance auth.Auth
|
||||
}
|
||||
|
||||
// getAPIUrl 获取接口请求地址
|
||||
func (handler Handler) getAPIUrl(scope string, routes ...string) string {
|
||||
func (handler Driver) getAPIUrl(scope string, routes ...string) string {
|
||||
serverURL, err := url.Parse(handler.Policy.Server)
|
||||
if err != nil {
|
||||
return ""
|
||||
|
@ -51,7 +51,7 @@ func (handler Handler) getAPIUrl(scope string, routes ...string) string {
|
|||
}
|
||||
|
||||
// Get 获取文件内容
|
||||
func (handler Handler) Get(ctx context.Context, path string) (response.RSCloser, error) {
|
||||
func (handler Driver) Get(ctx context.Context, path string) (response.RSCloser, error) {
|
||||
// 尝试获取速度限制 TODO 是否需要在这里限制?
|
||||
speedLimit := 0
|
||||
if user, ok := ctx.Value(fsctx.UserCtx).(model.User); ok {
|
||||
|
@ -86,7 +86,7 @@ func (handler Handler) Get(ctx context.Context, path string) (response.RSCloser,
|
|||
}
|
||||
|
||||
// Put 将文件流保存到指定目录
|
||||
func (handler Handler) Put(ctx context.Context, file io.ReadCloser, dst string, size uint64) error {
|
||||
func (handler Driver) Put(ctx context.Context, file io.ReadCloser, dst string, size uint64) error {
|
||||
defer file.Close()
|
||||
|
||||
// 凭证有效期
|
||||
|
@ -133,7 +133,7 @@ func (handler Handler) Put(ctx context.Context, file io.ReadCloser, dst string,
|
|||
|
||||
// Delete 删除一个或多个文件,
|
||||
// 返回未删除的文件,及遇到的最后一个错误
|
||||
func (handler Handler) Delete(ctx context.Context, files []string) ([]string, error) {
|
||||
func (handler Driver) Delete(ctx context.Context, files []string) ([]string, error) {
|
||||
// 封装接口请求正文
|
||||
reqBody := serializer.RemoteDeleteRequest{
|
||||
Files: files,
|
||||
|
@ -177,7 +177,7 @@ func (handler Handler) Delete(ctx context.Context, files []string) ([]string, er
|
|||
}
|
||||
|
||||
// Thumb 获取文件缩略图
|
||||
func (handler Handler) Thumb(ctx context.Context, path string) (*response.ContentResponse, error) {
|
||||
func (handler Driver) Thumb(ctx context.Context, path string) (*response.ContentResponse, error) {
|
||||
sourcePath := base64.RawURLEncoding.EncodeToString([]byte(path))
|
||||
thumbURL := handler.getAPIUrl("thumb") + "/" + sourcePath
|
||||
ttl := model.GetIntSetting("preview_timeout", 60)
|
||||
|
@ -193,7 +193,7 @@ func (handler Handler) Thumb(ctx context.Context, path string) (*response.Conten
|
|||
}
|
||||
|
||||
// Source 获取外链URL
|
||||
func (handler Handler) Source(
|
||||
func (handler Driver) Source(
|
||||
ctx context.Context,
|
||||
path string,
|
||||
baseURL url.URL,
|
||||
|
@ -238,7 +238,7 @@ func (handler Handler) Source(
|
|||
}
|
||||
|
||||
// Token 获取上传策略和认证Token
|
||||
func (handler Handler) Token(ctx context.Context, TTL int64, key string) (serializer.UploadCredential, error) {
|
||||
func (handler Driver) Token(ctx context.Context, TTL int64, key string) (serializer.UploadCredential, error) {
|
||||
// 生成回调地址
|
||||
siteURL := model.GetSiteURL()
|
||||
apiBaseURI, _ := url.Parse("/api/v3/callback/remote/" + key)
|
||||
|
@ -256,7 +256,7 @@ func (handler Handler) Token(ctx context.Context, TTL int64, key string) (serial
|
|||
return handler.getUploadCredential(ctx, policy, TTL)
|
||||
}
|
||||
|
||||
func (handler Handler) getUploadCredential(ctx context.Context, policy serializer.UploadPolicy, TTL int64) (serializer.UploadCredential, error) {
|
||||
func (handler Driver) getUploadCredential(ctx context.Context, policy serializer.UploadPolicy, TTL int64) (serializer.UploadCredential, error) {
|
||||
policyEncoded, err := policy.EncodeUploadPolicy()
|
||||
if err != nil {
|
||||
return serializer.UploadCredential{}, err
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
|
||||
func TestHandler_Token(t *testing.T) {
|
||||
asserts := assert.New(t)
|
||||
handler := Handler{
|
||||
handler := Driver{
|
||||
Policy: &model.Policy{
|
||||
MaxSize: 10,
|
||||
AutoRename: true,
|
||||
|
@ -59,7 +59,7 @@ func TestHandler_Source(t *testing.T) {
|
|||
|
||||
// 无法获取上下文
|
||||
{
|
||||
handler := Handler{
|
||||
handler := Driver{
|
||||
Policy: &model.Policy{Server: "/"},
|
||||
AuthInstance: auth.HMACAuth{},
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ func TestHandler_Source(t *testing.T) {
|
|||
|
||||
// 成功
|
||||
{
|
||||
handler := Handler{
|
||||
handler := Driver{
|
||||
Policy: &model.Policy{Server: "/"},
|
||||
AuthInstance: auth.HMACAuth{},
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ func TestHandler_Source(t *testing.T) {
|
|||
|
||||
// 成功 预览
|
||||
{
|
||||
handler := Handler{
|
||||
handler := Driver{
|
||||
Policy: &model.Policy{Server: "/"},
|
||||
AuthInstance: auth.HMACAuth{},
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ func (m ClientMock) Request(method, target string, body io.Reader, opts ...reque
|
|||
|
||||
func TestHandler_Delete(t *testing.T) {
|
||||
asserts := assert.New(t)
|
||||
handler := Handler{
|
||||
handler := Driver{
|
||||
Policy: &model.Policy{
|
||||
SecretKey: "test",
|
||||
Server: "http://test.com",
|
||||
|
@ -194,7 +194,7 @@ func TestHandler_Delete(t *testing.T) {
|
|||
|
||||
func TestHandler_Get(t *testing.T) {
|
||||
asserts := assert.New(t)
|
||||
handler := Handler{
|
||||
handler := Driver{
|
||||
Policy: &model.Policy{
|
||||
SecretKey: "test",
|
||||
Server: "http://test.com",
|
||||
|
@ -254,7 +254,7 @@ func TestHandler_Get(t *testing.T) {
|
|||
|
||||
func TestHandler_Put(t *testing.T) {
|
||||
asserts := assert.New(t)
|
||||
handler := Handler{
|
||||
handler := Driver{
|
||||
Policy: &model.Policy{
|
||||
Type: "remote",
|
||||
SecretKey: "test",
|
||||
|
@ -338,7 +338,7 @@ func TestHandler_Put(t *testing.T) {
|
|||
|
||||
func TestHandler_Thumb(t *testing.T) {
|
||||
asserts := assert.New(t)
|
||||
handler := Handler{
|
||||
handler := Driver{
|
||||
Policy: &model.Policy{
|
||||
Type: "remote",
|
||||
SecretKey: "test",
|
||||
|
|
|
@ -25,7 +25,7 @@ func SlaveUpload(c *gin.Context) {
|
|||
c.JSON(200, serializer.Err(serializer.CodePolicyNotAllowed, err.Error(), err))
|
||||
return
|
||||
}
|
||||
fs.Handler = local.Handler{}
|
||||
fs.Handler = local.Driver{}
|
||||
|
||||
// 从请求中取得上传策略
|
||||
uploadPolicyRaw := c.GetHeader("X-Policy")
|
||||
|
|
Loading…
Add table
Reference in a new issue