mirror of
https://github.com/OpenListTeam/OpenList.git
synced 2026-10-10 04:53:09 +08:00
893457cd50
* fix(aliyundrive): limit callback concurrency - Share proxy callback admission by Aliyun user identity and hold permits for complete response-body lifetimes. - Retry only verified callback-capacity rejections while preserving direct redirects and server download limiting. - Map exhausted temporary capacity to S3 SlowDown through the merged OpenListTeam gofakes3 module. - Cover shared limits, lifecycle release, cancellation, retry classification, and the S3 HTTP response. Co-authored-by: Codex <267193182+codex@users.noreply.github.com> # Conflicts: # go.mod # go.sum # server/s3/pager.go * fix(op): separate redirect and proxy link cache entries - Include redirect mode in the link cache key for all drivers. - Cover both redirect-to-proxy and proxy-to-redirect cache reuse. Co-authored-by: Codex <267193182+codex@users.noreply.github.com> * fix(proxy): close range bodies before opening next - make ServeHTTP own each range body and preserve cleanup failures - remove the aggregate range closer and pass range readers directly - replace the obsolete callback transport test with focused lifecycle coverage Co-authored-by: Codex <267193182+codex@users.noreply.github.com> --------- Co-authored-by: nostalume <nostalucent@gmail.com> Co-authored-by: Codex <267193182+codex@users.noreply.github.com>
72 lines
2.0 KiB
Go
72 lines
2.0 KiB
Go
package op
|
|
|
|
import (
|
|
"context"
|
|
"io"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/OpenListTeam/OpenList/v4/internal/driver"
|
|
"github.com/OpenListTeam/OpenList/v4/internal/model"
|
|
"github.com/OpenListTeam/OpenList/v4/internal/stream"
|
|
"github.com/OpenListTeam/OpenList/v4/pkg/http_range"
|
|
)
|
|
|
|
type linkModeDriver struct {
|
|
driver.Driver
|
|
storage model.Storage
|
|
calls int
|
|
}
|
|
|
|
func (d *linkModeDriver) Config() driver.Config { return driver.Config{} }
|
|
|
|
func (d *linkModeDriver) GetStorage() *model.Storage { return &d.storage }
|
|
|
|
func (d *linkModeDriver) Get(context.Context, string) (model.Obj, error) {
|
|
return &model.Object{Name: "file"}, nil
|
|
}
|
|
|
|
func (d *linkModeDriver) Link(_ context.Context, _ model.Obj, args model.LinkArgs) (*model.Link, error) {
|
|
d.calls++
|
|
expiration := time.Minute
|
|
if args.Redirect {
|
|
return &model.Link{URL: "https://example.com/file", Expiration: &expiration}, nil
|
|
}
|
|
return &model.Link{
|
|
RangeReader: stream.RangeReaderFunc(func(context.Context, http_range.Range) (io.ReadCloser, error) {
|
|
return io.NopCloser(strings.NewReader("file")), nil
|
|
}),
|
|
Expiration: &expiration,
|
|
}, nil
|
|
}
|
|
|
|
func TestLinkCacheSeparatesRedirectAndProxy(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
name string
|
|
firstRedirect bool
|
|
}{
|
|
{name: "redirect then proxy", firstRedirect: true},
|
|
{name: "proxy then redirect", firstRedirect: false},
|
|
} {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
d := &linkModeDriver{storage: model.Storage{MountPath: "/" + t.Name()}}
|
|
for _, redirect := range []bool{tc.firstRedirect, !tc.firstRedirect, tc.firstRedirect, !tc.firstRedirect} {
|
|
link, _, err := Link(context.Background(), d, "/file", model.LinkArgs{Redirect: redirect})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if redirect && (link.URL == "" || link.RangeReader != nil) {
|
|
t.Fatalf("redirect link has wrong shape: %+v", link)
|
|
}
|
|
if !redirect && (link.URL != "" || link.RangeReader == nil) {
|
|
t.Fatalf("proxy link has wrong shape: %+v", link)
|
|
}
|
|
}
|
|
if d.calls != 2 {
|
|
t.Fatalf("expected one driver call per mode, got %d", d.calls)
|
|
}
|
|
})
|
|
}
|
|
}
|