mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-30 05:56:54 -05:00
integrate restful api with v2 service
This commit is contained in:
parent
d277e566e0
commit
75a571a4ce
18
app/restful-api/config.proto
Normal file
18
app/restful-api/config.proto
Normal file
@ -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;
|
||||
}
|
@ -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
|
||||
}
|
||||
|
39
app/restful-api/service.go
Normal file
39
app/restful-api/service.go
Normal file
@ -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
|
||||
}
|
13
app/restful-api/service_test.go
Normal file
13
app/restful-api/service_test.go
Normal file
@ -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")
|
||||
}
|
Loading…
Reference in New Issue
Block a user