mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-12 11:24:08 +00:00
feat: add gblob scheme support for extension (#1358)
This commit is contained in:
18 files changed
+2664
-147
No files matched your search
@@ -0,0 +1,117 @@
|
||||
package download
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/GopeedLab/gopeed/pkg/download/engine"
|
||||
"github.com/GopeedLab/gopeed/pkg/download/engine/inject/stream"
|
||||
"github.com/dop251/goja"
|
||||
)
|
||||
|
||||
type engineSession struct {
|
||||
engine *engine.Engine
|
||||
|
||||
mu sync.Mutex
|
||||
refs int
|
||||
closed bool
|
||||
}
|
||||
|
||||
func newEngineSession(e *engine.Engine) *engineSession {
|
||||
return &engineSession{engine: e}
|
||||
}
|
||||
|
||||
func (s *engineSession) SetEngine(e *engine.Engine) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
s.engine = e
|
||||
}
|
||||
|
||||
func (s *engineSession) Retain() {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
if s.closed {
|
||||
return
|
||||
}
|
||||
s.refs++
|
||||
}
|
||||
|
||||
func (s *engineSession) Release() {
|
||||
s.mu.Lock()
|
||||
if s.refs > 0 {
|
||||
s.refs--
|
||||
}
|
||||
shouldClose := s.refs == 0 && !s.closed
|
||||
if shouldClose {
|
||||
s.closed = true
|
||||
}
|
||||
s.mu.Unlock()
|
||||
if shouldClose {
|
||||
if s.engine != nil {
|
||||
go s.engine.Close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *engineSession) CloseIfIdle() {
|
||||
s.mu.Lock()
|
||||
shouldClose := s.refs == 0 && !s.closed
|
||||
if shouldClose {
|
||||
s.closed = true
|
||||
}
|
||||
s.mu.Unlock()
|
||||
if shouldClose {
|
||||
if s.engine != nil {
|
||||
s.engine.Close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeStreamChunk(data any) ([]byte, error) {
|
||||
switch v := data.(type) {
|
||||
case nil:
|
||||
return nil, nil
|
||||
case string:
|
||||
return []byte(v), nil
|
||||
case []byte:
|
||||
return v, nil
|
||||
case goja.ArrayBuffer:
|
||||
return v.Bytes(), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported stream chunk type: %T", data)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *Downloader) newExtensionEngine() (*engine.Engine, *engineSession) {
|
||||
session := newEngineSession(nil)
|
||||
engineCfg := &stream.Config{
|
||||
CreateBlobObjectURL: func(data []byte, contentType string) (string, error) {
|
||||
return d.gblob.CreateBlob(data, contentType)
|
||||
},
|
||||
CreateWritableStreamObjectURL: func() (string, error) {
|
||||
return d.gblob.CreateWritableStream(session)
|
||||
},
|
||||
WriteWritableStreamObjectURL: func(url string, data any) error {
|
||||
chunk, err := normalizeStreamChunk(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return d.gblob.Write(url, chunk)
|
||||
},
|
||||
CloseWritableStreamObjectURL: func(url string) error {
|
||||
return d.gblob.CloseSource(url)
|
||||
},
|
||||
AbortWritableStreamObjectURL: func(url string, reason string) error {
|
||||
return d.gblob.AbortSource(url, fmt.Errorf("%s", reason))
|
||||
},
|
||||
RevokeObjectURL: func(url string) error {
|
||||
return d.gblob.Revoke(url)
|
||||
},
|
||||
}
|
||||
e := engine.NewEngine(&engine.Config{
|
||||
ProxyConfig: d.cfg.Proxy,
|
||||
StreamConfig: engineCfg,
|
||||
})
|
||||
session.SetEngine(e)
|
||||
return e, session
|
||||
}
|
||||
Reference in new issue
Block a user