diff --git a/weed/server/webdav_server.go b/weed/server/webdav_server.go index 1289a1321..5f242689f 100644 --- a/weed/server/webdav_server.go +++ b/weed/server/webdav_server.go @@ -570,6 +570,14 @@ func (f *WebDavFile) Read(p []byte) (readSize int, err error) { if fileSize == 0 { return 0, io.EOF } + if len(f.entry.Content) > 0 { + if f.off >= int64(len(f.entry.Content)) { + return 0, io.EOF + } + readSize = copy(p, f.entry.Content[f.off:]) + f.off += int64(readSize) + return readSize, nil + } if f.visibleIntervals == nil { f.visibleIntervals, err = filer.NonOverlappingVisibleIntervals(f.ctx, f.fs.filerClient.GetLookupFileIdFunction(), f.entry.GetChunks(), 0, fileSize) if err != nil { diff --git a/weed/server/webdav_server_test.go b/weed/server/webdav_server_test.go index e33e9b8c1..705b2f30d 100644 --- a/weed/server/webdav_server_test.go +++ b/weed/server/webdav_server_test.go @@ -3,6 +3,7 @@ package weed_server import ( "context" "fmt" + "io" "net" "os" "testing" @@ -104,3 +105,28 @@ func TestWebDavFile_Read_ManifestResolveFailure(t *testing.T) { assert.Error(t, err) assert.Equal(t, 0, n) } + +// Small files stored inline in the entry have no chunks to read from. +func TestWebDavFile_Read_InlineContent(t *testing.T) { + content := []byte("hello inline") + entry := &filer_pb.Entry{ + Name: "small.txt", + Attributes: &filer_pb.FuseAttributes{FileSize: uint64(len(content))}, + Content: content, + } + filerAddr := startFakeWebDavFiler(t, &noVolumeFiler{}) + fc := wdclient.NewFilerClient([]pb.ServerAddress{filerAddr}, grpc.WithTransportCredentials(insecure.NewCredentials()), "") + t.Cleanup(fc.Close) + f := &WebDavFile{fs: &WebDavFileSystem{filerClient: fc}, name: "/small.txt", entry: entry, ctx: context.Background()} + + got, err := io.ReadAll(f) + assert.NoError(t, err) + assert.Equal(t, content, got) + + _, err = f.Seek(6, io.SeekStart) + assert.NoError(t, err) + buf := make([]byte, 3) + n, err := f.Read(buf) + assert.NoError(t, err) + assert.Equal(t, "inl", string(buf[:n])) +}