diff --git a/sdks/storage/cdsapi/presigned.go b/sdks/storage/cdsapi/presigned.go index b357e71..99bf8b2 100644 --- a/sdks/storage/cdsapi/presigned.go +++ b/sdks/storage/cdsapi/presigned.go @@ -23,6 +23,16 @@ func (c *Client) Presigned() *PresignedService { } } +const PresignedObjectListByPathPath = "/v1/presigned/object/listByPath" + +type PresignedObjectListByPath struct { + ObjectListByPath +} + +func (c *PresignedService) ObjectListByPath(req PresignedObjectListByPath, expireIn int) (string, error) { + return c.presign(req, PresignedObjectListByPathPath, http.MethodGet, expireIn) +} + const PresignedObjectDownloadByPathPath = "/v1/presigned/object/downloadByPath" type PresignedObjectDownloadByPath struct { diff --git a/sdks/storage/cdsapi/presigned_test.go b/sdks/storage/cdsapi/presigned_test.go index f4071c9..7379951 100644 --- a/sdks/storage/cdsapi/presigned_test.go +++ b/sdks/storage/cdsapi/presigned_test.go @@ -39,6 +39,31 @@ func Test_Presigned(t *testing.T) { }) } +func Test_PresignedObjectListByPath(t *testing.T) { + cli := NewClient(&Config{ + URL: "http://localhost:7890", + AccessKey: "123456", + SecretKey: "123456", + }) + + Convey("下载文件", t, func() { + pre := cli.Presigned() + url, err := pre.ObjectListByPath(PresignedObjectListByPath{ + ObjectListByPath: ObjectListByPath{ + UserID: 1, + PackageID: 12, + Path: "a/", + IsPrefix: true, + NoRecursive: true, + MaxKeys: 10, + ContinuationToken: "123456", + }, + }, 100) + So(err, ShouldEqual, nil) + t.Logf("url: %s", url) + }) +} + func Test_PresignedObjectDownloadByPath(t *testing.T) { cli := NewClient(&Config{ URL: "http://localhost:7890", diff --git a/utils/io2/io.go b/utils/io2/io.go index 5107ae0..da57b92 100644 --- a/utils/io2/io.go +++ b/utils/io2/io.go @@ -1,6 +1,9 @@ package io2 -import "io" +import ( + "io" + "sync" +) type PromiseWriteCloser[T any] interface { io.Writer @@ -35,6 +38,7 @@ type readCloserHook struct { callback func(closer io.ReadCloser) once int isBefore bool // callback调用时机,true则在closer的Close之前调用 + lock *sync.Mutex } func (hook *readCloserHook) Read(buf []byte) (n int, err error) { @@ -42,6 +46,9 @@ func (hook *readCloserHook) Read(buf []byte) (n int, err error) { } func (hook *readCloserHook) Close() error { + hook.lock.Lock() + defer hook.lock.Unlock() + if hook.once == onceDone { return hook.readCloser.Close() } @@ -69,6 +76,7 @@ func BeforeReadClosing(closer io.ReadCloser, callback func(closer io.ReadCloser) callback: callback, once: onceDisabled, isBefore: true, + lock: &sync.Mutex{}, } } @@ -78,6 +86,7 @@ func AfterReadClosed(closer io.ReadCloser, callback func(closer io.ReadCloser)) callback: callback, once: onceDisabled, isBefore: false, + lock: &sync.Mutex{}, } } @@ -87,16 +96,22 @@ func AfterReadClosedOnce(closer io.ReadCloser, callback func(closer io.ReadClose callback: callback, once: onceEnabled, isBefore: false, + lock: &sync.Mutex{}, } } type afterEOF struct { inner io.ReadCloser callback func(str io.ReadCloser, err error) + lock *sync.Mutex } func (hook *afterEOF) Read(buf []byte) (n int, err error) { n, err = hook.inner.Read(buf) + + hook.lock.Lock() + defer hook.lock.Unlock() + if hook.callback != nil { if err == io.EOF { hook.callback(hook.inner, nil) @@ -111,6 +126,10 @@ func (hook *afterEOF) Read(buf []byte) (n int, err error) { func (hook *afterEOF) Close() error { err := hook.inner.Close() + + hook.lock.Lock() + defer hook.lock.Unlock() + if hook.callback != nil { hook.callback(hook.inner, io.ErrClosedPipe) hook.callback = nil @@ -122,6 +141,7 @@ func AfterEOF(str io.ReadCloser, callback func(str io.ReadCloser, err error)) io return &afterEOF{ inner: str, callback: callback, + lock: &sync.Mutex{}, } } diff --git a/utils/io2/range.go b/utils/io2/range.go index a4a0b35..46b4add 100644 --- a/utils/io2/range.go +++ b/utils/io2/range.go @@ -37,16 +37,22 @@ func (r *rng) Read(p []byte) (n int, err error) { need := math2.Min(*r.length, int64(len(p))) rd, err := r.inner.Read(p[:need]) - if err != nil { - r.err = err - return rd, io.EOF - } *r.length -= int64(rd) if *r.length == 0 { r.err = io.EOF } + if err == nil { + return rd, nil + } + + if err != io.EOF { + r.err = err + return rd, err + } + + r.err = io.EOF return rd, nil }