From 75a571a4ce8871de8c021c1a14e401591358793a Mon Sep 17 00:00:00 2001 From: Shelikhoo Date: Mon, 6 Sep 2021 13:11:30 +0100 Subject: [PATCH] integrate restful api with v2 service --- app/restful-api/config.proto | 18 +++++++++++++++ app/restful-api/restful-api.go | 33 +++++++++++++++++++++++----- app/restful-api/service.go | 39 +++++++++++++++++++++++++++++++++ app/restful-api/service_test.go | 13 +++++++++++ 4 files changed, 98 insertions(+), 5 deletions(-) create mode 100644 app/restful-api/config.proto create mode 100644 app/restful-api/service.go create mode 100644 app/restful-api/service_test.go diff --git a/app/restful-api/config.proto b/app/restful-api/config.proto new file mode 100644 index 000000000..6d646ea7a --- /dev/null +++ b/app/restful-api/config.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +package v2ray.app.restfulapi; +option csharp_namespace = "V2Ray.App.Restapi"; +option go_package = "github.com/v2fly/v2ray-core/v4/app/restful-api;restful_api"; +option java_package = "com.v2ray.core.app.restapi"; +option java_multiple_files = true; + +import "common/protoext/extensions.proto"; + +message Config{ + option (v2ray.core.common.protoext.message_opt).type = "service"; + option (v2ray.core.common.protoext.message_opt).short_name = "restful-api"; + + string listen_addr = 1; + int32 listen_port = 2; + string auth_token = 3; +} \ No newline at end of file diff --git a/app/restful-api/restful-api.go b/app/restful-api/restful-api.go index eb1472417..89ea0abeb 100644 --- a/app/restful-api/restful-api.go +++ b/app/restful-api/restful-api.go @@ -2,7 +2,10 @@ package restful_api import ( "github.com/gin-gonic/gin" + "github.com/v2fly/v2ray-core/v4/common/net" + "github.com/v2fly/v2ray-core/v4/transport/internet" "net/http" + "strings" ) type StatsUser struct { @@ -55,7 +58,7 @@ func stats(c *gin.Context) { c.JSON(http.StatusOK, response) } -func loggerReboot(c *gin.Context) { +func loggerReboot(c *gin.Context) { c.JSON(http.StatusOK, gin.H{}) } @@ -71,8 +74,9 @@ func TokenAuthMiddleware() gin.HandlerFunc { } } -func Start() error { - r := gin.New() +func (r *restfulService) start() error { + r.Engine = gin.New() + r.GET("/ping", func(c *gin.Context) { c.JSON(200, gin.H{ "message": "pong", @@ -87,9 +91,28 @@ func Start() error { v1.POST("/logger/reboot", loggerReboot) } - if err := r.Run(":3000"); err != nil { - return err + var listener net.Listener + var err error + address := net.ParseAddress(r.config.ListenAddr) + + switch { + case address.Family().IsIP(): + listener, err = internet.ListenSystem(r.ctx, &net.TCPAddr{IP: address.IP(), Port: int(r.config.ListenPort)}, nil) + case strings.EqualFold(address.Domain(), "localhost"): + listener, err = internet.ListenSystem(r.ctx, &net.TCPAddr{IP: net.IP{127, 0, 0, 1}, Port: int(r.config.ListenPort)}, nil) + default: + return newError("restful api cannot listen on the address: ", address) } + if err != nil { + return newError("restful api cannot listen on the port ", r.config.ListenPort).Base(err) + } + + r.listener = listener + go func() { + if err := r.RunListener(listener); err != nil { + newError("unable to serve restful api").WriteToLog() + } + }() return nil } diff --git a/app/restful-api/service.go b/app/restful-api/service.go new file mode 100644 index 000000000..5dfa3a3e9 --- /dev/null +++ b/app/restful-api/service.go @@ -0,0 +1,39 @@ +package restful_api + +import ( + "context" + "github.com/gin-gonic/gin" + "net" + "sync" +) + +//go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen + +type restfulService struct { + *gin.Engine + + listener net.Listener + config *Config + access sync.Mutex + + ctx context.Context +} + +func (r *restfulService) Type() interface{} { + return (*struct{})(nil) +} + +func (r *restfulService) Start() error { + defer r.access.Unlock() + r.access.Lock() + return r.start() +} + +func (r *restfulService) Close() error { + defer r.access.Unlock() + r.access.Lock() + if r.listener != nil { + return r.listener.Close() + } + return nil +} diff --git a/app/restful-api/service_test.go b/app/restful-api/service_test.go new file mode 100644 index 000000000..f05953297 --- /dev/null +++ b/app/restful-api/service_test.go @@ -0,0 +1,13 @@ +package restful_api + +import ( + "github.com/stretchr/testify/assert" + "reflect" + "testing" +) + +func TestTypeReturnAnonymousType(t *testing.T) { + service := restfulService{} + serviceType := service.Type() + assert.Empty(t, reflect.TypeOf(serviceType).Name(), "must return anonymous type") +}