diff --git a/models/migration.go b/models/migration.go
index c1c3620..5ca26a4 100644
--- a/models/migration.go
+++ b/models/migration.go
@@ -109,6 +109,7 @@ solid #e9e9e9;"bgcolor="#fff">
= 300 {
decodeErr = json.Unmarshal([]byte(respBody), &errResp)
if decodeErr != nil {
return "", sysError(decodeErr)
@@ -388,7 +478,7 @@ func (client *Client) request(ctx context.Context, method string, url string, bo
func (client *Client) requestWithStr(ctx context.Context, method string, url string, body string, expectedCode int) (string, *RespError) {
// 发送请求
bodyReader := ioutil.NopCloser(strings.NewReader(body))
- return client.request(ctx, method, url, bodyReader, expectedCode,
+ return client.request(ctx, method, url, bodyReader,
request.WithContentLength(int64(len(body))),
)
}
diff --git a/pkg/filesystem/driver/onedrive/handller.go b/pkg/filesystem/driver/onedrive/handller.go
index 27f0525..f0c0516 100644
--- a/pkg/filesystem/driver/onedrive/handller.go
+++ b/pkg/filesystem/driver/onedrive/handller.go
@@ -6,6 +6,7 @@ import (
model "github.com/HFO4/cloudreve/models"
"github.com/HFO4/cloudreve/pkg/filesystem/fsctx"
"github.com/HFO4/cloudreve/pkg/filesystem/response"
+ "github.com/HFO4/cloudreve/pkg/request"
"github.com/HFO4/cloudreve/pkg/serializer"
"io"
"net/url"
@@ -13,20 +14,51 @@ import (
// Driver OneDrive 适配器
type Driver struct {
- Policy *model.Policy
- Client *Client
+ Policy *model.Policy
+ Client *Client
+ HTTPClient request.Client
}
// Get 获取文件
func (handler Driver) Get(ctx context.Context, path string) (response.RSCloser, error) {
- return nil, errors.New("未实现")
+ // 获取文件源地址
+ downloadURL, err := handler.Source(
+ ctx,
+ path,
+ url.URL{},
+ int64(model.GetIntSetting("preview_timeout", 60)),
+ false,
+ 0,
+ )
+ if err != nil {
+ return nil, err
+ }
+
+ // 获取文件数据流
+ resp, err := handler.HTTPClient.Request(
+ "GET",
+ downloadURL,
+ nil,
+ request.WithContext(ctx),
+ ).CheckHTTPResponse(200).GetRSCloser()
+ if err != nil {
+ return nil, err
+ }
+
+ resp.SetFirstFakeChunk()
+
+ // 尝试自主获取文件大小
+ if file, ok := ctx.Value(fsctx.FileModelCtx).(model.File); ok {
+ resp.SetContentLength(int64(file.Size))
+ }
+
+ return resp, nil
}
// Put 将文件流保存到指定目录
func (handler Driver) Put(ctx context.Context, file io.ReadCloser, dst string, size uint64) error {
defer file.Close()
- _, err := handler.Client.PutFile(ctx, dst, file)
- return err
+ return handler.Client.Upload(ctx, dst, int(size), file)
}
// Delete 删除一个或多个文件,
@@ -67,7 +99,11 @@ func (handler Driver) Source(
isDownload bool,
speed int,
) (string, error) {
- return "", errors.New("未实现")
+ res, err := handler.Client.Meta(ctx, "", path)
+ if err == nil {
+ return res.DownloadURL, nil
+ }
+ return "", err
}
// Token 获取上传会话URL
diff --git a/pkg/filesystem/driver/onedrive/types.go b/pkg/filesystem/driver/onedrive/types.go
index b7b0970..5386c93 100644
--- a/pkg/filesystem/driver/onedrive/types.go
+++ b/pkg/filesystem/driver/onedrive/types.go
@@ -1,6 +1,7 @@
package onedrive
import (
+ "io"
"sync"
)
@@ -29,6 +30,7 @@ type FileInfo struct {
Size uint64 `json:"size"`
Image imageInfo `json:"image"`
ParentReference parentReference `json:"parentReference"`
+ DownloadURL string `json:"@microsoft.graph.downloadUrl"`
}
type imageInfo struct {
@@ -79,4 +81,18 @@ type ThumbResponse struct {
Value []map[string]interface{} `json:"value"`
}
+// Chunk 文件分片
+type Chunk struct {
+ Offset int
+ ChunkSize int
+ Total int
+ Retried int
+ Reader io.Reader
+}
+
+// IsLast 返回是否为最后一个分片
+func (chunk *Chunk) IsLast() bool {
+ return chunk.Total-chunk.Offset == chunk.ChunkSize
+}
+
var callbackSignal sync.Map
diff --git a/pkg/filesystem/filesystem.go b/pkg/filesystem/filesystem.go
index 4c32883..a2599c3 100644
--- a/pkg/filesystem/filesystem.go
+++ b/pkg/filesystem/filesystem.go
@@ -186,8 +186,9 @@ func (fs *FileSystem) DispatchHandler() error {
case "onedrive":
client, err := onedrive.NewClient(currentPolicy)
fs.Handler = onedrive.Driver{
- Policy: currentPolicy,
- Client: client,
+ Policy: currentPolicy,
+ Client: client,
+ HTTPClient: request.HTTPClient{},
}
return err
default:
diff --git a/pkg/request/request.go b/pkg/request/request.go
index a1dfc34..98a523d 100644
--- a/pkg/request/request.go
+++ b/pkg/request/request.go
@@ -85,7 +85,19 @@ func WithCredential(instance auth.Auth, ttl int64) Option {
// WithHeader 设置请求Header
func WithHeader(header http.Header) Option {
return optionFunc(func(o *options) {
- o.header = header
+ for k, v := range header {
+ o.header[k] = v
+ }
+ })
+}
+
+// WithoutHeader 设置清除请求Header
+func WithoutHeader(header []string) Option {
+ return optionFunc(func(o *options) {
+ for _, v := range header {
+ delete(o.header, v)
+ }
+
})
}
diff --git a/pkg/webdav/prop.go b/pkg/webdav/prop.go
index 7921d9a..636745f 100644
--- a/pkg/webdav/prop.go
+++ b/pkg/webdav/prop.go
@@ -280,7 +280,7 @@ loop:
// The file doesn't implement the optional DeadPropsHolder interface, so
// all patches are forbidden.
- pstat := Propstat{Status: http.StatusForbidden}
+ pstat := Propstat{Status: http.StatusOK}
for _, patch := range patches {
for _, p := range patch.Props {
pstat.Props = append(pstat.Props, Property{XMLName: p.XMLName})
diff --git a/service/callback/upload.go b/service/callback/upload.go
index 3db4d55..226b79a 100644
--- a/service/callback/upload.go
+++ b/service/callback/upload.go
@@ -160,7 +160,7 @@ func (service *OneDriveCallback) PreProcess(c *gin.Context) serializer.Response
callbackSession := callbackSessionRaw.(*serializer.UploadSession)
// 获取文件信息
- info, err := fs.Handler.(onedrive.Driver).Client.Meta(context.Background(), service.ID)
+ info, err := fs.Handler.(onedrive.Driver).Client.Meta(context.Background(), service.ID, "")
if err != nil {
return serializer.Err(serializer.CodeUploadFailed, "文件元信息查询失败", err)
}