Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: use FFI instead socket #848

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions bind/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package bind

import (
"encoding/json"
"errors"
"github.com/GopeedLab/gopeed/pkg/api"
"github.com/GopeedLab/gopeed/pkg/api/model"
)

// Global singleton instance
var instance *api.Instance

func Init(config *model.StartConfig) (err error) {
if instance != nil {
return nil
}

Check warning on line 16 in bind/common.go

View check run for this annotation

Codecov / codecov/patch

bind/common.go#L13-L16

Added lines #L13 - L16 were not covered by tests

config.ProductionMode = true
instance, err = api.Create(config)
return

Check warning on line 20 in bind/common.go

View check run for this annotation

Codecov / codecov/patch

bind/common.go#L18-L20

Added lines #L18 - L20 were not covered by tests
}

func Invoke(request *api.Request) string {
if instance == nil {
return BuildResult(errors.New("instance not initialized"))
}
return jsonEncode(api.Invoke(instance, request))

Check warning on line 27 in bind/common.go

View check run for this annotation

Codecov / codecov/patch

bind/common.go#L23-L27

Added lines #L23 - L27 were not covered by tests
}

func BuildResult(data any) string {
if err, ok := data.(error); ok {
buf, _ := json.Marshal(model.NewErrorResult[any](err.Error()))
return string(buf)
}
return jsonEncode(model.NewOkResult(data))

Check warning on line 35 in bind/common.go

View check run for this annotation

Codecov / codecov/patch

bind/common.go#L30-L35

Added lines #L30 - L35 were not covered by tests
}

func jsonEncode(data any) string {
buf, _ := json.Marshal(data)
return string(buf)

Check warning on line 40 in bind/common.go

View check run for this annotation

Codecov / codecov/patch

bind/common.go#L38-L40

Added lines #L38 - L40 were not covered by tests
}
31 changes: 18 additions & 13 deletions bind/desktop/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,32 @@ package main
import "C"
import (
"encoding/json"
"github.com/GopeedLab/gopeed/pkg/rest"
"github.com/GopeedLab/gopeed/pkg/rest/model"
"github.com/GopeedLab/gopeed/bind"
"github.com/GopeedLab/gopeed/pkg/api"
"github.com/GopeedLab/gopeed/pkg/api/model"
)

func main() {}

//export Start
func Start(cfg *C.char) (int, *C.char) {
//export Init
func Init(cfg *C.char) *C.char {
var config model.StartConfig
if err := json.Unmarshal([]byte(C.GoString(cfg)), &config); err != nil {
return 0, C.CString(err.Error())
return C.CString(err.Error())
}
config.ProductionMode = true
realPort, err := rest.Start(&config)
if err != nil {
return 0, C.CString(err.Error())
if err := bind.Init(&config); err != nil {
return C.CString(err.Error())
}
return realPort, nil

return nil
}

//export Stop
func Stop() {
rest.Stop()
//export Invoke
func Invoke(req *C.char) *C.char {
var request api.Request
if err := json.Unmarshal([]byte(C.GoString(req)), &request); err != nil {
return C.CString(bind.BuildResult(err))
}

return C.CString(bind.Invoke(&request))
}
19 changes: 7 additions & 12 deletions bind/mobile/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,15 @@ package libgopeed
// #cgo LDFLAGS: -static-libstdc++
import "C"
import (
"encoding/json"
"github.com/GopeedLab/gopeed/pkg/rest"
"github.com/GopeedLab/gopeed/pkg/rest/model"
"github.com/GopeedLab/gopeed/bind"
"github.com/GopeedLab/gopeed/pkg/api"
"github.com/GopeedLab/gopeed/pkg/api/model"
)

func Start(cfg string) (int, error) {
var config model.StartConfig
if err := json.Unmarshal([]byte(cfg), &config); err != nil {
return 0, err
}
config.ProductionMode = true
return rest.Start(&config)
func Init(cfg *model.StartConfig) error {
return bind.Init(cfg)
}

func Stop() {
rest.Stop()
func Invoke(request *api.Request) string {
return bind.Invoke(request)
}
14 changes: 10 additions & 4 deletions cmd/api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,21 @@ package main

import (
"github.com/GopeedLab/gopeed/cmd"
"github.com/GopeedLab/gopeed/pkg/rest/model"
"github.com/GopeedLab/gopeed/pkg/api/model"
"github.com/GopeedLab/gopeed/pkg/base"
)

// only for local development
func main() {
cfg := &model.StartConfig{
Network: "tcp",
Address: "127.0.0.1:9999",
Storage: model.StorageBolt,
Storage: model.StorageBolt,
DownloadConfig: &base.DownloaderStoreConfig{
Http: &base.DownloaderHttpConfig{
Enable: true,
Host: "127.0.0.1",
Port: 9999,
},
},
WebEnable: true,
}
cmd.Start(cfg)
Expand Down
32 changes: 18 additions & 14 deletions cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
import (
_ "embed"
"fmt"
"github.com/GopeedLab/gopeed/pkg/api"
"github.com/GopeedLab/gopeed/pkg/api/model"
"github.com/GopeedLab/gopeed/pkg/base"
"github.com/GopeedLab/gopeed/pkg/rest"
"github.com/GopeedLab/gopeed/pkg/rest/model"
"net/http"
"os"
"os/signal"
"path/filepath"
Expand All @@ -18,20 +17,22 @@

func Start(cfg *model.StartConfig) {
fmt.Println(banner)
srv, listener, err := rest.BuildServer(cfg)
instance, err := api.Create(cfg)

Check warning on line 20 in cmd/server.go

View check run for this annotation

Codecov / codecov/patch

cmd/server.go#L20

Added line #L20 was not covered by tests
if err != nil {
panic(err)
}
downloadCfg, err := rest.Downloader.GetConfig()
if err != nil {
panic(err)

downloadCfgResult := instance.GetConfig()
if downloadCfgResult.HasError() {
panic(downloadCfgResult.Msg)

Check warning on line 27 in cmd/server.go

View check run for this annotation

Codecov / codecov/patch

cmd/server.go#L25-L27

Added lines #L25 - L27 were not covered by tests
}
downloadCfg := downloadCfgResult.Data

Check warning on line 29 in cmd/server.go

View check run for this annotation

Codecov / codecov/patch

cmd/server.go#L29

Added line #L29 was not covered by tests
if downloadCfg.FirstLoad {
// Set default download config
if cfg.DownloadConfig != nil {
cfg.DownloadConfig.Merge(downloadCfg)
// TODO Use PatchConfig
rest.Downloader.PutConfig(cfg.DownloadConfig)
instance.PutConfig(cfg.DownloadConfig)

Check warning on line 35 in cmd/server.go

View check run for this annotation

Codecov / codecov/patch

cmd/server.go#L35

Added line #L35 was not covered by tests
downloadCfg = cfg.DownloadConfig
}

Expand All @@ -48,25 +49,28 @@
}
if downloadDir != "" {
downloadCfg.DownloadDir = downloadDir
rest.Downloader.PutConfig(downloadCfg)
instance.PutConfig(downloadCfg)

Check warning on line 52 in cmd/server.go

View check run for this annotation

Codecov / codecov/patch

cmd/server.go#L52

Added line #L52 was not covered by tests
}
}
}
watchExit()

fmt.Printf("Server start success on http://%s\n", listener.Addr().String())
if err := srv.Serve(listener); err != nil && err != http.ErrServerClosed {
watchExit(instance)

port, start, err := api.ListenHttp(cfg.DownloadConfig.Http, instance)
if err != nil {

Check warning on line 60 in cmd/server.go

View check run for this annotation

Codecov / codecov/patch

cmd/server.go#L57-L60

Added lines #L57 - L60 were not covered by tests
panic(err)
}
fmt.Printf("Server start success on http://%s:%d\n", cfg.DownloadConfig.Http.Host, port)
start()

Check warning on line 64 in cmd/server.go

View check run for this annotation

Codecov / codecov/patch

cmd/server.go#L63-L64

Added lines #L63 - L64 were not covered by tests
}

func watchExit() {
func watchExit(instance *api.Instance) {

Check warning on line 67 in cmd/server.go

View check run for this annotation

Codecov / codecov/patch

cmd/server.go#L67

Added line #L67 was not covered by tests
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
go func() {
sig := <-sigs
fmt.Printf("Server is shutting down due to signal: %s\n", sig)
rest.Downloader.Close()
instance.Close()

Check warning on line 73 in cmd/server.go

View check run for this annotation

Codecov / codecov/patch

cmd/server.go#L73

Added line #L73 was not covered by tests
os.Exit(0)
}()
}
8 changes: 4 additions & 4 deletions cmd/web/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
)

type args struct {
Address *string `json:"address"`
Host *string `json:"host"`
Port *int `json:"port"`
Username *string `json:"username"`
Password *string `json:"password"`
Expand All @@ -24,7 +24,7 @@ type args struct {

func parse() *args {
var cliArgs args
cliArgs.Address = flag.String("A", "0.0.0.0", "Bind Address")
cliArgs.Host = flag.String("H", "0.0.0.0", "Bind Host")
cliArgs.Port = flag.Int("P", 9999, "Bind Port")
cliArgs.Username = flag.String("u", "gopeed", "HTTP Basic Auth Username")
cliArgs.Password = flag.String("p", "", "HTTP Basic Auth Pwd")
Expand All @@ -35,8 +35,8 @@ func parse() *args {

// args priority: config file > cli args
cfgArgs := loadConfig(*cliArgs.configPath)
if cfgArgs.Address == nil {
cfgArgs.Address = cliArgs.Address
if cfgArgs.Host == nil {
cfgArgs.Host = cliArgs.Host
}
if cfgArgs.Port == nil {
cfgArgs.Port = cliArgs.Port
Expand Down
17 changes: 12 additions & 5 deletions cmd/web/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ package main

import (
"embed"
"fmt"
"github.com/GopeedLab/gopeed/cmd"
"github.com/GopeedLab/gopeed/pkg/rest/model"
"github.com/GopeedLab/gopeed/pkg/api/model"
"github.com/GopeedLab/gopeed/pkg/base"
"io/fs"
"os"
"path/filepath"
Expand Down Expand Up @@ -42,12 +42,19 @@ func main() {
dir = filepath.Dir(exe)
}

if args.DownloadConfig == nil {
args.DownloadConfig = &base.DownloaderStoreConfig{}
}
args.DownloadConfig.Http = &base.DownloaderHttpConfig{
Enable: true,
Host: *args.Host,
Port: *args.Port,
ApiToken: *args.ApiToken,
}

cfg := &model.StartConfig{
Network: "tcp",
Address: fmt.Sprintf("%s:%d", *args.Address, *args.Port),
Storage: model.StorageBolt,
StorageDir: filepath.Join(dir, "storage"),
ApiToken: *args.ApiToken,
DownloadConfig: args.DownloadConfig,
ProductionMode: true,
WebEnable: true,
Expand Down
2 changes: 1 addition & 1 deletion internal/protocol/bt/fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ func (f *Fetcher) doUpload(fromUpload bool) {
}
}

// Get torrent stats maybe panic, see https://github.com/anacrolix/torrent/issues/972
// get torrent stats maybe panic, see https://github.com/anacrolix/torrent/issues/972
func (f *Fetcher) torrentStats() torrent.TorrentStats {
defer func() {
if r := recover(); r != nil {
Expand Down
4 changes: 2 additions & 2 deletions internal/protocol/http/fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ func (f *Fetcher) Resolve(req *base.Request) error {
file.Name = filename
}
}
// Get file filePath by URL
// get file filePath by URL
if file.Name == "" {
file.Name = path.Base(httpReq.URL.Path)
}
Expand Down Expand Up @@ -499,7 +499,7 @@ func (fm *FetcherManager) ParseName(u string) string {
if err != nil {
return ""
}
// Get filePath by URL
// get filePath by URL
name = path.Base(url.Path)
// If file name is empty, use host name
if name == "" || name == "/" || name == "." {
Expand Down
Loading
Loading