Fix: cannot edit file in remote server / Modify: separate preview and text-file content controller

This commit is contained in:
HFO4
2020-01-04 15:49:08 +08:00
parent 93dc25aabb
commit d94896041e
10 changed files with 84 additions and 16 deletions

View File

@@ -93,7 +93,6 @@ func (fs *FileSystem) Compress(ctx context.Context, folderIDs, fileIDs []uint) (
}
// cancelCompress 取消压缩进程
// TODO 测试
func (fs *FileSystem) cancelCompress(ctx context.Context, zipWriter *zip.Writer, file *os.File, path string) {
util.Log().Debug("客户端取消压缩请求")
zipWriter.Close()

View File

@@ -88,14 +88,23 @@ func (fs *FileSystem) GetPhysicalFileContent(ctx context.Context, path string) (
}
// Preview 预览文件
func (fs *FileSystem) Preview(ctx context.Context, path string) (*response.ContentResponse, error) {
// path - 文件虚拟路径
// isText - 是否为文本文件,文本文件会忽略重定向,直接由
// 服务端拉取中转给用户,故会对文件大小进行限制
func (fs *FileSystem) Preview(ctx context.Context, path string, isText bool) (*response.ContentResponse, error) {
err := fs.resetFileIfNotExist(ctx, path)
if err != nil {
return nil, err
}
// 如果是文本文件预览,需要检查大小限制
sizeLimit := model.GetIntSetting("maxEditSize", 2<<20)
if fs.FileTarget[0].Size > uint64(sizeLimit) {
return nil, ErrFileSizeTooBig
}
// 是否直接返回文件内容
if fs.Policy.IsDirectlyPreview() {
if isText || fs.Policy.IsDirectlyPreview() {
resp, err := fs.GetDownloadContent(ctx, path)
if err != nil {
return nil, err

View File

@@ -510,7 +510,7 @@ func TestFileSystem_Preview(t *testing.T) {
User: &model.User{},
}
mock.ExpectQuery("SELECT(.+)").WillReturnRows(sqlmock.NewRows([]string{"id"}))
resp, err := fs.Preview(ctx, "/1.txt")
resp, err := fs.Preview(ctx, "/1.txt", false)
asserts.NoError(mock.ExpectationsWereMet())
asserts.Error(err)
asserts.Nil(resp)
@@ -530,7 +530,7 @@ func TestFileSystem_Preview(t *testing.T) {
},
},
}
resp, err := fs.Preview(ctx, "/1.txt")
resp, err := fs.Preview(ctx, "/1.txt", false)
asserts.Error(err)
asserts.Nil(resp)
}
@@ -550,7 +550,7 @@ func TestFileSystem_Preview(t *testing.T) {
},
},
}
resp, err := fs.Preview(ctx, "/1.txt")
resp, err := fs.Preview(ctx, "/1.txt", false)
asserts.NoError(err)
asserts.NotNil(resp)
asserts.False(resp.Redirect)
@@ -573,9 +573,31 @@ func TestFileSystem_Preview(t *testing.T) {
},
}
asserts.NoError(cache.Set("setting_preview_timeout", "233", 0))
resp, err := fs.Preview(ctx, "/1.txt")
resp, err := fs.Preview(ctx, "/1.txt", false)
asserts.NoError(err)
asserts.NotNil(resp)
asserts.True(resp.Redirect)
}
// 文本文件,大小超出限制
{
fs := FileSystem{
User: &model.User{},
}
fs.FileTarget = []model.File{
{
SourceName: "tests/file1.txt",
PolicyID: 1,
Policy: model.Policy{
Model: gorm.Model{ID: 1},
Type: "remote",
},
Size: 11,
},
}
asserts.NoError(cache.Set("setting_maxEditSize", "10", 0))
resp, err := fs.Preview(ctx, "/1.txt", true)
asserts.Equal(ErrFileSizeTooBig, err)
asserts.Nil(resp)
}
}

View File

@@ -151,6 +151,7 @@ func (resp *Response) CheckHTTPResponse(status int) *Response {
type nopRSCloser struct {
body io.ReadCloser
size int64
}
// GetRSCloser 返回带有空seeker的body reader
@@ -161,6 +162,7 @@ func (resp *Response) GetRSCloser() (response.RSCloser, error) {
return nopRSCloser{
body: resp.Response.Body,
size: resp.Response.ContentLength,
}, resp.Err
}
@@ -174,7 +176,16 @@ func (instance nopRSCloser) Close() error {
return instance.body.Close()
}
// 实现 nopRSCloser seeker
// 实现 nopRSCloser seeker, 只实现seek开头/结尾以便http.ServeContent用于确定正文大小
func (instance nopRSCloser) Seek(offset int64, whence int) (int64, error) {
if offset == 0 {
switch whence {
case io.SeekStart:
return 0, nil
case io.SeekEnd:
return instance.size, nil
}
}
return 0, errors.New("未实现")
}

View File

@@ -156,14 +156,20 @@ func TestResponse_GetRSCloser(t *testing.T) {
// 正常
{
resp := Response{
Response: &http.Response{Body: ioutil.NopCloser(strings.NewReader("123"))},
Response: &http.Response{ContentLength: 3, Body: ioutil.NopCloser(strings.NewReader("123"))},
}
res, err := resp.GetRSCloser()
asserts.NoError(err)
content, err := ioutil.ReadAll(res)
asserts.NoError(err)
asserts.Equal("123", string(content))
_, err = res.Seek(0, 0)
offset, err := res.Seek(0, 0)
asserts.NoError(err)
asserts.Equal(int64(0), offset)
offset, err = res.Seek(0, 2)
asserts.NoError(err)
asserts.Equal(int64(3), offset)
_, err = res.Seek(1, 2)
asserts.Error(err)
asserts.NoError(res.Close())
}

View File

@@ -26,7 +26,7 @@ func TestRemoteCallback(t *testing.T) {
"http://test/test/url",
testMock.Anything,
testMock.Anything,
).Return(Response{
).Return(&Response{
Err: nil,
Response: &http.Response{
StatusCode: 200,

View File

@@ -230,7 +230,7 @@ func (h *Handler) handleGetHeadPost(w http.ResponseWriter, r *http.Request, fs *
ctx := r.Context()
rs, err := fs.Preview(ctx, reqPath)
rs, err := fs.Preview(ctx, reqPath, false)
if err != nil {
if err == filesystem.ErrObjectNotExist {
return http.StatusNotFound, err