mirror of
https://github.com/v2fly/v2ray-core.git
synced 2024-12-05 17:56:26 -05:00
json config parser
This commit is contained in:
parent
e866ff24a4
commit
5a311cbe08
@ -1,34 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package dns
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
v2net "v2ray.com/core/common/net"
|
||||
)
|
||||
|
||||
func (this *Config) UnmarshalJSON(data []byte) error {
|
||||
type JsonConfig struct {
|
||||
Servers []*v2net.IPOrDomain `json:"servers"`
|
||||
Hosts map[string]*v2net.IPOrDomain `json:"hosts"`
|
||||
}
|
||||
jsonConfig := new(JsonConfig)
|
||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
this.NameServers = make([]*v2net.Endpoint, len(jsonConfig.Servers))
|
||||
for idx, server := range jsonConfig.Servers {
|
||||
this.NameServers[idx] = &v2net.Endpoint{
|
||||
Network: v2net.Network_UDP,
|
||||
Address: server,
|
||||
Port: 53,
|
||||
}
|
||||
}
|
||||
|
||||
if jsonConfig.Hosts != nil {
|
||||
this.Hosts = jsonConfig.Hosts
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
package router
|
||||
|
||||
//go:generate go run chinaip_gen.go
|
File diff suppressed because it is too large
Load Diff
@ -1,22 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package router
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"v2ray.com/core/common/log"
|
||||
)
|
||||
|
||||
func parseChinaIPRule(data []byte) (*RoutingRule, error) {
|
||||
rawRule := new(JsonRule)
|
||||
err := json.Unmarshal(data, rawRule)
|
||||
if err != nil {
|
||||
log.Error("Router: Invalid router rule: ", err)
|
||||
return nil, err
|
||||
}
|
||||
return &RoutingRule{
|
||||
Tag: rawRule.OutboundTag,
|
||||
Ip: chinaIPs,
|
||||
}, nil
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package router_test
|
||||
|
||||
import (
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
. "v2ray.com/core/app/router"
|
||||
v2net "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/testing/assert"
|
||||
)
|
||||
|
||||
func makeDestination(ip string) v2net.Destination {
|
||||
return v2net.TCPDestination(v2net.IPAddress(net.ParseIP(ip)), 80)
|
||||
}
|
||||
|
||||
func TestChinaIPJson(t *testing.T) {
|
||||
assert := assert.On(t)
|
||||
|
||||
rule := ParseRule([]byte(`{
|
||||
"type": "chinaip",
|
||||
"outboundTag": "x"
|
||||
}`))
|
||||
assert.String(rule.Tag).Equals("x")
|
||||
cond, err := rule.BuildCondition()
|
||||
assert.Error(err).IsNil()
|
||||
assert.Bool(cond.Apply(makeDestination("121.14.1.189"))).IsTrue() // sina.com.cn
|
||||
assert.Bool(cond.Apply(makeDestination("101.226.103.106"))).IsTrue() // qq.com
|
||||
assert.Bool(cond.Apply(makeDestination("115.239.210.36"))).IsTrue() // image.baidu.com
|
||||
assert.Bool(cond.Apply(makeDestination("120.135.126.1"))).IsTrue()
|
||||
|
||||
assert.Bool(cond.Apply(makeDestination("8.8.8.8"))).IsFalse()
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package router
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"v2ray.com/core/common/log"
|
||||
)
|
||||
|
||||
func parseChinaSitesRule(data []byte) (*RoutingRule, error) {
|
||||
rawRule := new(JsonRule)
|
||||
err := json.Unmarshal(data, rawRule)
|
||||
if err != nil {
|
||||
log.Error("Router: Invalid router rule: ", err)
|
||||
return nil, err
|
||||
}
|
||||
return &RoutingRule{
|
||||
Tag: rawRule.OutboundTag,
|
||||
Domain: chinaSitesDomains,
|
||||
}, nil
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package router_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "v2ray.com/core/app/router"
|
||||
v2net "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/testing/assert"
|
||||
)
|
||||
|
||||
func makeDomainDestination(domain string) v2net.Destination {
|
||||
return v2net.TCPDestination(v2net.DomainAddress(domain), 80)
|
||||
}
|
||||
|
||||
func TestChinaSitesJson(t *testing.T) {
|
||||
assert := assert.On(t)
|
||||
|
||||
rule := ParseRule([]byte(`{
|
||||
"type": "chinasites",
|
||||
"outboundTag": "y"
|
||||
}`))
|
||||
assert.String(rule.Tag).Equals("y")
|
||||
cond, err := rule.BuildCondition()
|
||||
assert.Error(err).IsNil()
|
||||
assert.Bool(cond.Apply(makeDomainDestination("v.qq.com"))).IsTrue()
|
||||
assert.Bool(cond.Apply(makeDomainDestination("www.163.com"))).IsTrue()
|
||||
assert.Bool(cond.Apply(makeDomainDestination("ngacn.cc"))).IsTrue()
|
||||
assert.Bool(cond.Apply(makeDomainDestination("12306.cn"))).IsTrue()
|
||||
|
||||
assert.Bool(cond.Apply(makeDomainDestination("v2ray.com"))).IsFalse()
|
||||
}
|
@ -44,7 +44,7 @@ func NewRouter(config *Config, space app.Space) *Router {
|
||||
}
|
||||
|
||||
if !space.HasApp(dns.APP_ID) {
|
||||
log.Error("DNS: Router is not found in the space.")
|
||||
log.Error("Router: DNS is not found in the space.")
|
||||
return app.ErrMissingApplication
|
||||
}
|
||||
r.dnsServer = space.GetApp(dns.APP_ID).(dns.Server)
|
||||
|
@ -32,7 +32,7 @@ type ApplicationFactory interface {
|
||||
}
|
||||
|
||||
var (
|
||||
applicationFactoryCache map[string]ApplicationFactory
|
||||
applicationFactoryCache = make(map[string]ApplicationFactory)
|
||||
)
|
||||
|
||||
func RegisterApplicationFactory(name string, factory ApplicationFactory) error {
|
||||
|
@ -1,39 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package loader_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
. "v2ray.com/core/common/loader"
|
||||
"v2ray.com/core/testing/assert"
|
||||
)
|
||||
|
||||
type TestConfigA struct {
|
||||
V int
|
||||
}
|
||||
|
||||
type TestConfigB struct {
|
||||
S string
|
||||
}
|
||||
|
||||
func TestCreatorCache(t *testing.T) {
|
||||
assert := assert.On(t)
|
||||
|
||||
cache := ConfigCreatorCache{}
|
||||
creator1 := func() interface{} { return &TestConfigA{} }
|
||||
creator2 := func() interface{} { return &TestConfigB{} }
|
||||
cache.RegisterCreator("1", creator1)
|
||||
|
||||
loader := NewJSONConfigLoader(cache, "test", "")
|
||||
rawA, err := loader.LoadWithID([]byte(`{"V": 2}`), "1")
|
||||
assert.Error(err).IsNil()
|
||||
instA := rawA.(*TestConfigA)
|
||||
assert.Int(instA.V).Equals(2)
|
||||
|
||||
cache.RegisterCreator("2", creator2)
|
||||
rawB, err := loader.LoadWithID([]byte(`{"S": "a"}`), "2")
|
||||
assert.Error(err).IsNil()
|
||||
instB := rawB.(*TestConfigB)
|
||||
assert.String(instB.S).Equals("a")
|
||||
}
|
@ -23,7 +23,7 @@ func GetType(message proto.Message) string {
|
||||
}
|
||||
|
||||
func GetInstance(messageType string) (interface{}, error) {
|
||||
mType := proto.MessageType(messageType)
|
||||
mType := proto.MessageType(messageType).Elem()
|
||||
if mType == nil {
|
||||
return nil, errors.New("Unknown type: " + messageType)
|
||||
}
|
||||
|
@ -1,69 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package net
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"v2ray.com/core/common/log"
|
||||
)
|
||||
|
||||
func parseIntPort(data []byte) (Port, error) {
|
||||
var intPort uint32
|
||||
err := json.Unmarshal(data, &intPort)
|
||||
if err != nil {
|
||||
return Port(0), err
|
||||
}
|
||||
return PortFromInt(intPort)
|
||||
}
|
||||
|
||||
func parseStringPort(data []byte) (Port, Port, error) {
|
||||
var s string
|
||||
err := json.Unmarshal(data, &s)
|
||||
if err != nil {
|
||||
return Port(0), Port(0), err
|
||||
}
|
||||
pair := strings.SplitN(s, "-", 2)
|
||||
if len(pair) == 0 {
|
||||
return Port(0), Port(0), ErrInvalidPortRange
|
||||
}
|
||||
if len(pair) == 1 {
|
||||
port, err := PortFromString(pair[0])
|
||||
return port, port, err
|
||||
}
|
||||
|
||||
fromPort, err := PortFromString(pair[0])
|
||||
if err != nil {
|
||||
return Port(0), Port(0), err
|
||||
}
|
||||
toPort, err := PortFromString(pair[1])
|
||||
if err != nil {
|
||||
return Port(0), Port(0), err
|
||||
}
|
||||
return fromPort, toPort, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements encoding/json.Unmarshaler.UnmarshalJSON
|
||||
func (this *PortRange) UnmarshalJSON(data []byte) error {
|
||||
port, err := parseIntPort(data)
|
||||
if err == nil {
|
||||
this.From = uint32(port)
|
||||
this.To = uint32(port)
|
||||
return nil
|
||||
}
|
||||
|
||||
from, to, err := parseStringPort(data)
|
||||
if err == nil {
|
||||
this.From = uint32(from)
|
||||
this.To = uint32(to)
|
||||
if this.From > this.To {
|
||||
log.Error("Invalid port range ", this.From, " -> ", this.To)
|
||||
return ErrInvalidPortRange
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Error("Invalid port range: ", string(data))
|
||||
return ErrInvalidPortRange
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package net_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
. "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/testing/assert"
|
||||
)
|
||||
|
||||
func TestIntPort(t *testing.T) {
|
||||
assert := assert.On(t)
|
||||
|
||||
var portRange PortRange
|
||||
err := json.Unmarshal([]byte("1234"), &portRange)
|
||||
assert.Error(err).IsNil()
|
||||
|
||||
assert.Uint32(portRange.From).Equals(1234)
|
||||
assert.Uint32(portRange.To).Equals(1234)
|
||||
}
|
||||
|
||||
func TestOverRangeIntPort(t *testing.T) {
|
||||
assert := assert.On(t)
|
||||
|
||||
var portRange PortRange
|
||||
err := json.Unmarshal([]byte("70000"), &portRange)
|
||||
assert.Error(err).Equals(ErrInvalidPortRange)
|
||||
|
||||
err = json.Unmarshal([]byte("-1"), &portRange)
|
||||
assert.Error(err).Equals(ErrInvalidPortRange)
|
||||
}
|
||||
|
||||
func TestSingleStringPort(t *testing.T) {
|
||||
assert := assert.On(t)
|
||||
|
||||
var portRange PortRange
|
||||
err := json.Unmarshal([]byte("\"1234\""), &portRange)
|
||||
assert.Error(err).IsNil()
|
||||
|
||||
assert.Uint32(portRange.From).Equals(1234)
|
||||
assert.Uint32(portRange.To).Equals(1234)
|
||||
}
|
||||
|
||||
func TestStringPairPort(t *testing.T) {
|
||||
assert := assert.On(t)
|
||||
|
||||
var portRange PortRange
|
||||
err := json.Unmarshal([]byte("\"1234-5678\""), &portRange)
|
||||
assert.Error(err).IsNil()
|
||||
|
||||
assert.Uint32(portRange.From).Equals(1234)
|
||||
assert.Uint32(portRange.To).Equals(5678)
|
||||
}
|
||||
|
||||
func TestOverRangeStringPort(t *testing.T) {
|
||||
assert := assert.On(t)
|
||||
|
||||
var portRange PortRange
|
||||
err := json.Unmarshal([]byte("\"65536\""), &portRange)
|
||||
assert.Error(err).Equals(ErrInvalidPortRange)
|
||||
|
||||
err = json.Unmarshal([]byte("\"70000-80000\""), &portRange)
|
||||
assert.Error(err).Equals(ErrInvalidPortRange)
|
||||
|
||||
err = json.Unmarshal([]byte("\"1-90000\""), &portRange)
|
||||
assert.Error(err).Equals(ErrInvalidPortRange)
|
||||
|
||||
err = json.Unmarshal([]byte("\"700-600\""), &portRange)
|
||||
assert.Error(err).Equals(ErrInvalidPortRange)
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package protocol
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
func (u *User) UnmarshalJSON(data []byte) error {
|
||||
type rawUser struct {
|
||||
EmailString string `json:"email"`
|
||||
LevelByte byte `json:"level"`
|
||||
}
|
||||
var rawUserValue rawUser
|
||||
if err := json.Unmarshal(data, &rawUserValue); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
u.Email = rawUserValue.EmailString
|
||||
u.Level = uint32(rawUserValue.LevelByte)
|
||||
|
||||
return nil
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package protocol_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
. "v2ray.com/core/common/protocol"
|
||||
"v2ray.com/core/testing/assert"
|
||||
)
|
||||
|
||||
func TestUserParsing(t *testing.T) {
|
||||
assert := assert.On(t)
|
||||
|
||||
user := new(User)
|
||||
err := json.Unmarshal([]byte(`{
|
||||
"id": "96edb838-6d68-42ef-a933-25f7ac3a9d09",
|
||||
"email": "love@v2ray.com",
|
||||
"level": 1,
|
||||
"alterId": 100
|
||||
}`), user)
|
||||
assert.Error(err).IsNil()
|
||||
assert.Byte(byte(user.Level)).Equals(1)
|
||||
assert.String(user.Email).Equals("love@v2ray.com")
|
||||
}
|
||||
|
||||
func TestInvalidUserJson(t *testing.T) {
|
||||
assert := assert.On(t)
|
||||
|
||||
user := new(User)
|
||||
err := json.Unmarshal([]byte(`{"email": 1234}`), user)
|
||||
assert.Error(err).IsNotNil()
|
||||
}
|
@ -2,6 +2,7 @@ package core
|
||||
|
||||
import (
|
||||
"v2ray.com/core/common"
|
||||
v2net "v2ray.com/core/common/net"
|
||||
)
|
||||
|
||||
func (this *AllocationStrategyConcurrency) GetValue() uint32 {
|
||||
@ -25,6 +26,13 @@ func (this *InboundConnectionConfig) GetAllocationStrategyValue() *AllocationStr
|
||||
return this.AllocationStrategy
|
||||
}
|
||||
|
||||
func (this *InboundConnectionConfig) GetListenOnValue() v2net.Address {
|
||||
if this.GetListenOn() == nil {
|
||||
return v2net.AnyIP
|
||||
}
|
||||
return this.ListenOn.AsAddress()
|
||||
}
|
||||
|
||||
func (this *InboundConnectionConfig) GetTypedSettings() (interface{}, error) {
|
||||
if this.GetSettings() == nil {
|
||||
return nil, common.ErrBadConfiguration
|
||||
|
@ -11,7 +11,7 @@ import (
|
||||
|
||||
type ConfigLoader func(input io.Reader) (*Config, error)
|
||||
|
||||
var configLoaderCache map[ConfigFormat]ConfigLoader
|
||||
var configLoaderCache = make(map[ConfigFormat]ConfigLoader)
|
||||
|
||||
func RegisterConfigLoader(format ConfigFormat, loader ConfigLoader) error {
|
||||
configLoaderCache[format] = loader
|
||||
|
@ -29,7 +29,7 @@ func NewInboundDetourHandlerAlways(space app.Space, config *InboundConnectionCon
|
||||
return nil, err
|
||||
}
|
||||
ich, err := proxyregistry.CreateInboundHandler(config.Settings.Type, space, ichConfig, &proxy.InboundHandlerMeta{
|
||||
Address: config.ListenOn.AsAddress(),
|
||||
Address: config.GetListenOnValue(),
|
||||
Port: i,
|
||||
Tag: config.Tag,
|
||||
StreamSettings: config.StreamSettings,
|
||||
|
@ -37,7 +37,7 @@ func NewInboundDetourHandlerDynamic(space app.Space, config *InboundConnectionCo
|
||||
return nil, err
|
||||
}
|
||||
ich, err := proxyregistry.CreateInboundHandler(config.Settings.Type, space, ichConfig, &proxy.InboundHandlerMeta{
|
||||
Address: config.ListenOn.AsAddress(),
|
||||
Address: config.GetListenOnValue(),
|
||||
Port: 0,
|
||||
Tag: config.Tag,
|
||||
StreamSettings: config.StreamSettings,
|
||||
@ -107,7 +107,8 @@ func (this *InboundDetourHandlerDynamic) refresh() error {
|
||||
for idx := range newIchs {
|
||||
err := retry.Timed(5, 100).On(func() error {
|
||||
port := this.pickUnusedPort()
|
||||
ich, err := proxyregistry.CreateInboundHandler(config.Settings.Type, this.space, config.Settings, &proxy.InboundHandlerMeta{
|
||||
ichConfig, _ := config.GetTypedSettings()
|
||||
ich, err := proxyregistry.CreateInboundHandler(config.Settings.Type, this.space, ichConfig, &proxy.InboundHandlerMeta{
|
||||
Address: config.ListenOn.AsAddress(), Port: port, Tag: config.Tag, StreamSettings: config.StreamSettings})
|
||||
if err != nil {
|
||||
delete(this.portsInUse, port)
|
||||
|
@ -3,10 +3,8 @@ package blackhole
|
||||
import (
|
||||
"v2ray.com/core/app"
|
||||
"v2ray.com/core/common/alloc"
|
||||
"v2ray.com/core/common/loader"
|
||||
v2net "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/proxy"
|
||||
"v2ray.com/core/proxy/registry"
|
||||
"v2ray.com/core/transport/ray"
|
||||
)
|
||||
|
||||
@ -49,7 +47,3 @@ func (this *Factory) StreamCapability() v2net.NetworkList {
|
||||
func (this *Factory) Create(space app.Space, config interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
||||
return NewBlackHole(space, config.(*Config), meta)
|
||||
}
|
||||
|
||||
func init() {
|
||||
registry.MustRegisterOutboundHandlerCreator(loader.GetType(new(Config)), new(Factory))
|
||||
}
|
||||
|
@ -1,41 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package blackhole
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"github.com/golang/protobuf/proto"
|
||||
"v2ray.com/core/common/loader"
|
||||
)
|
||||
|
||||
func (this *Config) UnmarshalJSON(data []byte) error {
|
||||
type JSONConfig struct {
|
||||
Response json.RawMessage `json:"response"`
|
||||
}
|
||||
jsonConfig := new(JSONConfig)
|
||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||
return errors.New("Blackhole: Failed to parse config: " + err.Error())
|
||||
}
|
||||
|
||||
if jsonConfig.Response != nil {
|
||||
response, _, err := configLoader.Load(jsonConfig.Response)
|
||||
if err != nil {
|
||||
return errors.New("Blackhole: Failed to parse response config: " + err.Error())
|
||||
}
|
||||
this.Response = loader.NewTypedSettings(response.(proto.Message))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
configLoader = loader.NewJSONConfigLoader(
|
||||
loader.NamedTypeMap{
|
||||
"none": loader.GetType(new(NoneResponse)),
|
||||
"http": loader.GetType(new(HTTPResponse)),
|
||||
},
|
||||
"type",
|
||||
"")
|
||||
)
|
@ -1,31 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package blackhole_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
. "v2ray.com/core/proxy/blackhole"
|
||||
"v2ray.com/core/testing/assert"
|
||||
)
|
||||
|
||||
func TestHTTPResponseJSON(t *testing.T) {
|
||||
assert := assert.On(t)
|
||||
|
||||
rawJson := `{
|
||||
"response": {
|
||||
"type": "http"
|
||||
}
|
||||
}`
|
||||
config := new(Config)
|
||||
err := json.Unmarshal([]byte(rawJson), config)
|
||||
assert.Error(err).IsNil()
|
||||
|
||||
assert.Int(int(config.Response.Type)).Equals(int(Response_HTTP))
|
||||
response, err := config.Response.GetInternalResponse()
|
||||
assert.Error(err).IsNil()
|
||||
|
||||
_, ok := response.(*HTTPResponse)
|
||||
assert.Bool(ok).IsTrue()
|
||||
}
|
11
proxy/blackhole/init.go
Normal file
11
proxy/blackhole/init.go
Normal file
@ -0,0 +1,11 @@
|
||||
package blackhole
|
||||
|
||||
import (
|
||||
"v2ray.com/core/common/loader"
|
||||
"v2ray.com/core/proxy/registry"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Must listed after config.pb.go
|
||||
registry.MustRegisterOutboundHandlerCreator(loader.GetType(new(Config)), new(Factory))
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package dokodemo
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
v2net "v2ray.com/core/common/net"
|
||||
)
|
||||
|
||||
func (this *Config) UnmarshalJSON(data []byte) error {
|
||||
type DokodemoConfig struct {
|
||||
Host *v2net.IPOrDomain `json:"address"`
|
||||
PortValue v2net.Port `json:"port"`
|
||||
NetworkList *v2net.NetworkList `json:"network"`
|
||||
TimeoutValue uint32 `json:"timeout"`
|
||||
Redirect bool `json:"followRedirect"`
|
||||
}
|
||||
rawConfig := new(DokodemoConfig)
|
||||
if err := json.Unmarshal(data, rawConfig); err != nil {
|
||||
return errors.New("Dokodemo: Failed to parse config: " + err.Error())
|
||||
}
|
||||
if rawConfig.Host != nil {
|
||||
this.Address = rawConfig.Host
|
||||
}
|
||||
this.Port = uint32(rawConfig.PortValue)
|
||||
this.NetworkList = rawConfig.NetworkList
|
||||
this.Timeout = rawConfig.TimeoutValue
|
||||
this.FollowRedirect = rawConfig.Redirect
|
||||
return nil
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package freedom
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (this *Config) UnmarshalJSON(data []byte) error {
|
||||
type JsonConfig struct {
|
||||
DomainStrategy string `json:"domainStrategy"`
|
||||
Timeout uint32 `json:"timeout"`
|
||||
}
|
||||
jsonConfig := new(JsonConfig)
|
||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||
return errors.New("Freedom: Failed to parse config: " + err.Error())
|
||||
}
|
||||
this.DomainStrategy = Config_AS_IS
|
||||
domainStrategy := strings.ToLower(jsonConfig.DomainStrategy)
|
||||
if domainStrategy == "useip" || domainStrategy == "use_ip" {
|
||||
this.DomainStrategy = Config_USE_IP
|
||||
}
|
||||
this.Timeout = jsonConfig.Timeout
|
||||
return nil
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package http
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
)
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler
|
||||
func (this *ServerConfig) UnmarshalJSON(data []byte) error {
|
||||
type JsonConfig struct {
|
||||
Timeout uint32 `json:"timeout"`
|
||||
}
|
||||
jsonConfig := new(JsonConfig)
|
||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||
return errors.New("HTTP: Failed to parse config: " + err.Error())
|
||||
}
|
||||
this.Timeout = jsonConfig.Timeout
|
||||
|
||||
return nil
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package http_test
|
@ -45,7 +45,7 @@ func MustRegisterOutboundHandlerCreator(name string, creator OutboundHandlerFact
|
||||
func CreateInboundHandler(name string, space app.Space, config interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) {
|
||||
creator, found := inboundFactories[name]
|
||||
if !found {
|
||||
return nil, common.ErrObjectNotFound
|
||||
return nil, errors.New("Proxy|Registry: Unknown inbound name: " + name)
|
||||
}
|
||||
if meta.StreamSettings == nil {
|
||||
meta.StreamSettings = &internet.StreamConfig{
|
||||
@ -63,7 +63,7 @@ func CreateInboundHandler(name string, space app.Space, config interface{}, meta
|
||||
func CreateOutboundHandler(name string, space app.Space, config interface{}, meta *proxy.OutboundHandlerMeta) (proxy.OutboundHandler, error) {
|
||||
creator, found := outboundFactories[name]
|
||||
if !found {
|
||||
return nil, common.ErrObjectNotFound
|
||||
return nil, errors.New("Proxy|Registry: Unknown outbound name: " + name)
|
||||
}
|
||||
if meta.StreamSettings == nil {
|
||||
meta.StreamSettings = &internet.StreamConfig{
|
||||
|
@ -1,60 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package shadowsocks
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"v2ray.com/core/common"
|
||||
"v2ray.com/core/common/loader"
|
||||
"v2ray.com/core/common/log"
|
||||
"v2ray.com/core/common/protocol"
|
||||
)
|
||||
|
||||
func (this *ServerConfig) UnmarshalJSON(data []byte) error {
|
||||
type JsonConfig struct {
|
||||
Cipher string `json:"method"`
|
||||
Password string `json:"password"`
|
||||
UDP bool `json:"udp"`
|
||||
Level byte `json:"level"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
jsonConfig := new(JsonConfig)
|
||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||
return errors.New("Shadowsocks: Failed to parse config: " + err.Error())
|
||||
}
|
||||
|
||||
this.UdpEnabled = jsonConfig.UDP
|
||||
|
||||
if len(jsonConfig.Password) == 0 {
|
||||
log.Error("Shadowsocks: Password is not specified.")
|
||||
return common.ErrBadConfiguration
|
||||
}
|
||||
account := &Account{
|
||||
Password: jsonConfig.Password,
|
||||
}
|
||||
jsonConfig.Cipher = strings.ToLower(jsonConfig.Cipher)
|
||||
switch jsonConfig.Cipher {
|
||||
case "aes-256-cfb":
|
||||
account.CipherType = CipherType_AES_256_CFB
|
||||
case "aes-128-cfb":
|
||||
account.CipherType = CipherType_AES_128_CFB
|
||||
case "chacha20":
|
||||
account.CipherType = CipherType_CHACHA20
|
||||
case "chacha20-ietf":
|
||||
account.CipherType = CipherType_CHACHA20_IEFT
|
||||
default:
|
||||
log.Error("Shadowsocks: Unknown cipher method: ", jsonConfig.Cipher)
|
||||
return common.ErrBadConfiguration
|
||||
}
|
||||
|
||||
this.User = &protocol.User{
|
||||
Email: jsonConfig.Email,
|
||||
Level: uint32(jsonConfig.Level),
|
||||
Account: loader.NewTypedSettings(account),
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package shadowsocks
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"v2ray.com/core/testing/assert"
|
||||
)
|
||||
|
||||
func TestConfigParsing(t *testing.T) {
|
||||
assert := assert.On(t)
|
||||
|
||||
rawJson := `{
|
||||
"method": "aes-128-cfb",
|
||||
"password": "v2ray-password"
|
||||
}`
|
||||
|
||||
config := new(ServerConfig)
|
||||
err := json.Unmarshal([]byte(rawJson), config)
|
||||
assert.Error(err).IsNil()
|
||||
|
||||
rawAccount, err = config.User.GetTypedAccount()
|
||||
assert.Error(err).IsNil()
|
||||
|
||||
account, ok := rawAccount.(*Account)
|
||||
assert.Bool(ok).IsTrue()
|
||||
|
||||
cipher, err := account.GetCipher()
|
||||
assert.Error(err).IsNil()
|
||||
assert.Int(cipher.KeySize()).Equals(16)
|
||||
assert.Bytes(account.GetCipherKey()).Equals([]byte{160, 224, 26, 2, 22, 110, 9, 80, 65, 52, 80, 20, 38, 243, 224, 241})
|
||||
}
|
@ -1,11 +1,6 @@
|
||||
package socks
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"v2ray.com/core/common"
|
||||
"v2ray.com/core/common/log"
|
||||
v2net "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/common/protocol"
|
||||
|
||||
@ -49,48 +44,3 @@ func (this *ServerConfig) GetNetAddress() v2net.Address {
|
||||
}
|
||||
return this.Address.AsAddress()
|
||||
}
|
||||
|
||||
const (
|
||||
AuthMethodNoAuth = "noauth"
|
||||
AuthMethodUserPass = "password"
|
||||
)
|
||||
|
||||
func (this *ServerConfig) UnmarshalJSON(data []byte) error {
|
||||
type SocksConfig struct {
|
||||
AuthMethod string `json:"auth"`
|
||||
Accounts []*Account `json:"accounts"`
|
||||
UDP bool `json:"udp"`
|
||||
Host *v2net.IPOrDomain `json:"ip"`
|
||||
Timeout uint32 `json:"timeout"`
|
||||
}
|
||||
|
||||
rawConfig := new(SocksConfig)
|
||||
if err := json.Unmarshal(data, rawConfig); err != nil {
|
||||
return errors.New("Socks: Failed to parse config: " + err.Error())
|
||||
}
|
||||
if rawConfig.AuthMethod == AuthMethodNoAuth {
|
||||
this.AuthType = AuthType_NO_AUTH
|
||||
} else if rawConfig.AuthMethod == AuthMethodUserPass {
|
||||
this.AuthType = AuthType_PASSWORD
|
||||
} else {
|
||||
log.Error("Socks: Unknown auth method: ", rawConfig.AuthMethod)
|
||||
return common.ErrBadConfiguration
|
||||
}
|
||||
|
||||
if len(rawConfig.Accounts) > 0 {
|
||||
this.Accounts = make(map[string]string, len(rawConfig.Accounts))
|
||||
for _, account := range rawConfig.Accounts {
|
||||
this.Accounts[account.Username] = account.Password
|
||||
}
|
||||
}
|
||||
|
||||
this.UdpEnabled = rawConfig.UDP
|
||||
if rawConfig.Host != nil {
|
||||
this.Address = rawConfig.Host
|
||||
}
|
||||
|
||||
if rawConfig.Timeout >= 0 {
|
||||
this.Timeout = rawConfig.Timeout
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -1,62 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package socks
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"v2ray.com/core/common/loader"
|
||||
v2net "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/common/protocol"
|
||||
)
|
||||
|
||||
func (this *Account) UnmarshalJSON(data []byte) error {
|
||||
type JsonConfig struct {
|
||||
Username string `json:"user"`
|
||||
Password string `json:"pass"`
|
||||
}
|
||||
jsonConfig := new(JsonConfig)
|
||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||
return errors.New("Socks: Failed to parse account: " + err.Error())
|
||||
}
|
||||
this.Username = jsonConfig.Username
|
||||
this.Password = jsonConfig.Password
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *ClientConfig) UnmarshalJSON(data []byte) error {
|
||||
type ServerConfig struct {
|
||||
Address *v2net.IPOrDomain `json:"address"`
|
||||
Port v2net.Port `json:"port"`
|
||||
Users []json.RawMessage `json:"users"`
|
||||
}
|
||||
type JsonConfig struct {
|
||||
Servers []*ServerConfig `json:"servers"`
|
||||
}
|
||||
jsonConfig := new(JsonConfig)
|
||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||
return errors.New("Socks|Client: Failed to parse config: " + err.Error())
|
||||
}
|
||||
this.Server = make([]*protocol.ServerEndpoint, len(jsonConfig.Servers))
|
||||
for idx, serverConfig := range jsonConfig.Servers {
|
||||
server := &protocol.ServerEndpoint{
|
||||
Address: serverConfig.Address,
|
||||
Port: uint32(serverConfig.Port),
|
||||
}
|
||||
for _, rawUser := range serverConfig.Users {
|
||||
user := new(protocol.User)
|
||||
if err := json.Unmarshal(rawUser, user); err != nil {
|
||||
return errors.New("Socks|Client: Failed to parse user: " + err.Error())
|
||||
}
|
||||
account := new(Account)
|
||||
if err := json.Unmarshal(rawUser, account); err != nil {
|
||||
return errors.New("Socks|Client: Failed to parse socks account: " + err.Error())
|
||||
}
|
||||
user.Account = loader.NewTypedSettings(account)
|
||||
server.User = append(server.User, user)
|
||||
}
|
||||
this.Server[idx] = server
|
||||
}
|
||||
return nil
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package socks_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"v2ray.com/core/proxy/registry"
|
||||
. "v2ray.com/core/proxy/socks"
|
||||
"v2ray.com/core/testing/assert"
|
||||
)
|
||||
|
||||
func TestDefaultIPAddress(t *testing.T) {
|
||||
assert := assert.On(t)
|
||||
|
||||
socksConfig, err := registry.CreateInboundConfig("socks", []byte(`{
|
||||
"auth": "noauth"
|
||||
}`))
|
||||
assert.Error(err).IsNil()
|
||||
assert.Address(socksConfig.(*ServerConfig).GetNetAddress()).EqualsString("127.0.0.1")
|
||||
}
|
@ -4,14 +4,13 @@ import (
|
||||
"testing"
|
||||
|
||||
"v2ray.com/core/common/alloc"
|
||||
"v2ray.com/core/common/loader"
|
||||
v2net "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/common/protocol"
|
||||
"v2ray.com/core/common/uuid"
|
||||
"v2ray.com/core/proxy/vmess"
|
||||
. "v2ray.com/core/proxy/vmess/encoding"
|
||||
"v2ray.com/core/testing/assert"
|
||||
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
)
|
||||
|
||||
func TestRequestSerialization(t *testing.T) {
|
||||
@ -25,9 +24,7 @@ func TestRequestSerialization(t *testing.T) {
|
||||
Id: uuid.New().String(),
|
||||
AlterId: 0,
|
||||
}
|
||||
anyAccount, err := ptypes.MarshalAny(account)
|
||||
assert.Error(err).IsNil()
|
||||
user.Account = anyAccount
|
||||
user.Account = loader.NewTypedSettings(account)
|
||||
|
||||
expectedRequest := &protocol.RequestHeader{
|
||||
Version: 1,
|
||||
|
@ -1,3 +1,13 @@
|
||||
package inbound
|
||||
|
||||
import ()
|
||||
|
||||
func (this *Config) GetDefaultValue() *DefaultConfig {
|
||||
if this.GetDefault() == nil {
|
||||
return &DefaultConfig{
|
||||
AlterId: 32,
|
||||
Level: 0,
|
||||
}
|
||||
}
|
||||
return this.Default
|
||||
}
|
||||
|
@ -1,85 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package inbound
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"v2ray.com/core/common/loader"
|
||||
"v2ray.com/core/common/protocol"
|
||||
"v2ray.com/core/proxy/vmess"
|
||||
)
|
||||
|
||||
func (this *DetourConfig) UnmarshalJSON(data []byte) error {
|
||||
type JsonDetourConfig struct {
|
||||
ToTag string `json:"to"`
|
||||
}
|
||||
jsonConfig := new(JsonDetourConfig)
|
||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||
return errors.New("VMess|Inbound: Failed to parse detour config: " + err.Error())
|
||||
}
|
||||
this.To = jsonConfig.ToTag
|
||||
return nil
|
||||
}
|
||||
|
||||
type FeaturesConfig struct {
|
||||
Detour *DetourConfig `json:"detour"`
|
||||
}
|
||||
|
||||
func (this *DefaultConfig) UnmarshalJSON(data []byte) error {
|
||||
type JsonDefaultConfig struct {
|
||||
AlterIDs uint16 `json:"alterId"`
|
||||
Level byte `json:"level"`
|
||||
}
|
||||
jsonConfig := new(JsonDefaultConfig)
|
||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||
return errors.New("VMess|Inbound: Failed to parse default config: " + err.Error())
|
||||
}
|
||||
this.AlterId = uint32(jsonConfig.AlterIDs)
|
||||
if this.AlterId == 0 {
|
||||
this.AlterId = 32
|
||||
}
|
||||
this.Level = uint32(jsonConfig.Level)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (this *Config) UnmarshalJSON(data []byte) error {
|
||||
type JsonConfig struct {
|
||||
Users []json.RawMessage `json:"clients"`
|
||||
Features *FeaturesConfig `json:"features"`
|
||||
Defaults *DefaultConfig `json:"default"`
|
||||
DetourConfig *DetourConfig `json:"detour"`
|
||||
}
|
||||
jsonConfig := new(JsonConfig)
|
||||
if err := json.Unmarshal(data, jsonConfig); err != nil {
|
||||
return errors.New("VMess|Inbound: Failed to parse config: " + err.Error())
|
||||
}
|
||||
this.Default = jsonConfig.Defaults
|
||||
if this.Default == nil {
|
||||
this.Default = &DefaultConfig{
|
||||
Level: 0,
|
||||
AlterId: 32,
|
||||
}
|
||||
}
|
||||
this.Detour = jsonConfig.DetourConfig
|
||||
// Backward compatibility
|
||||
if jsonConfig.Features != nil && jsonConfig.DetourConfig == nil {
|
||||
this.Detour = jsonConfig.Features.Detour
|
||||
}
|
||||
this.User = make([]*protocol.User, len(jsonConfig.Users))
|
||||
for idx, rawData := range jsonConfig.Users {
|
||||
user := new(protocol.User)
|
||||
if err := json.Unmarshal(rawData, user); err != nil {
|
||||
return errors.New("VMess|Inbound: Invalid user: " + err.Error())
|
||||
}
|
||||
account := new(vmess.Account)
|
||||
if err := json.Unmarshal(rawData, account); err != nil {
|
||||
return errors.New("VMess|Inbound: Invalid user: " + err.Error())
|
||||
}
|
||||
user.Account = loader.NewTypedSettings(account)
|
||||
this.User[idx] = user
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -268,7 +268,7 @@ func (this *Factory) Create(space app.Space, rawConfig interface{}, meta *proxy.
|
||||
packetDispatcher: space.GetApp(dispatcher.APP_ID).(dispatcher.PacketDispatcher),
|
||||
clients: allowedClients,
|
||||
detours: config.Detour,
|
||||
usersByEmail: NewUserByEmail(config.User, config.Default),
|
||||
usersByEmail: NewUserByEmail(config.User, config.GetDefaultValue()),
|
||||
meta: meta,
|
||||
}
|
||||
|
||||
|
@ -1,73 +0,0 @@
|
||||
// +build json
|
||||
|
||||
package outbound
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"v2ray.com/core/common"
|
||||
"v2ray.com/core/common/loader"
|
||||
"v2ray.com/core/common/log"
|
||||
v2net "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/common/protocol"
|
||||
"v2ray.com/core/common/serial"
|
||||
"v2ray.com/core/proxy/vmess"
|
||||
)
|
||||
|
||||
func (this *Config) UnmarshalJSON(data []byte) error {
|
||||
type RawConfigTarget struct {
|
||||
Address *v2net.IPOrDomain `json:"address"`
|
||||
Port v2net.Port `json:"port"`
|
||||
Users []json.RawMessage `json:"users"`
|
||||
}
|
||||
type RawOutbound struct {
|
||||
Receivers []*RawConfigTarget `json:"vnext"`
|
||||
}
|
||||
rawOutbound := &RawOutbound{}
|
||||
err := json.Unmarshal(data, rawOutbound)
|
||||
if err != nil {
|
||||
return errors.New("VMessOut: Failed to parse config: " + err.Error())
|
||||
}
|
||||
if len(rawOutbound.Receivers) == 0 {
|
||||
log.Error("VMessOut: 0 VMess receiver configured.")
|
||||
return common.ErrBadConfiguration
|
||||
}
|
||||
serverSpecs := make([]*protocol.ServerEndpoint, len(rawOutbound.Receivers))
|
||||
for idx, rec := range rawOutbound.Receivers {
|
||||
if len(rec.Users) == 0 {
|
||||
log.Error("VMess: 0 user configured for VMess outbound.")
|
||||
return common.ErrBadConfiguration
|
||||
}
|
||||
if rec.Address == nil {
|
||||
log.Error("VMess: Address is not set in VMess outbound config.")
|
||||
return common.ErrBadConfiguration
|
||||
}
|
||||
if rec.Address.AsAddress().String() == string([]byte{118, 50, 114, 97, 121, 46, 99, 111, 111, 108}) {
|
||||
rec.Address.Address = &v2net.IPOrDomain_Ip{
|
||||
Ip: serial.Uint32ToBytes(757086633, nil),
|
||||
}
|
||||
}
|
||||
spec := &protocol.ServerEndpoint{
|
||||
Address: rec.Address,
|
||||
Port: uint32(rec.Port),
|
||||
}
|
||||
for _, rawUser := range rec.Users {
|
||||
user := new(protocol.User)
|
||||
if err := json.Unmarshal(rawUser, user); err != nil {
|
||||
log.Error("VMess|Outbound: Invalid user: ", err)
|
||||
return err
|
||||
}
|
||||
account := new(vmess.Account)
|
||||
if err := json.Unmarshal(rawUser, account); err != nil {
|
||||
log.Error("VMess|Outbound: Invalid user: ", err)
|
||||
return err
|
||||
}
|
||||
user.Account = loader.NewTypedSettings(account)
|
||||
spec.User = append(spec.User, user)
|
||||
}
|
||||
serverSpecs[idx] = spec
|
||||
}
|
||||
this.Receiver = serverSpecs
|
||||
return nil
|
||||
}
|
52
tools/conf/blackhole.go
Normal file
52
tools/conf/blackhole.go
Normal file
@ -0,0 +1,52 @@
|
||||
package conf
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
||||
"v2ray.com/core/common/loader"
|
||||
"v2ray.com/core/proxy/blackhole"
|
||||
)
|
||||
|
||||
type NoneResponse struct{}
|
||||
|
||||
func (*NoneResponse) Build() (*loader.TypedSettings, error) {
|
||||
return loader.NewTypedSettings(new(blackhole.NoneResponse)), nil
|
||||
}
|
||||
|
||||
type HttpResponse struct{}
|
||||
|
||||
func (*HttpResponse) Build() (*loader.TypedSettings, error) {
|
||||
return loader.NewTypedSettings(new(blackhole.HTTPResponse)), nil
|
||||
}
|
||||
|
||||
type BlackholeConfig struct {
|
||||
Response json.RawMessage `json:"response"`
|
||||
}
|
||||
|
||||
func (this *BlackholeConfig) Build() (*loader.TypedSettings, error) {
|
||||
config := new(blackhole.Config)
|
||||
if this.Response != nil {
|
||||
response, _, err := configLoader.Load(this.Response)
|
||||
if err != nil {
|
||||
return nil, errors.New("Blackhole: Failed to parse response config: " + err.Error())
|
||||
}
|
||||
responseSettings, err := response.(Buildable).Build()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.Response = responseSettings
|
||||
}
|
||||
|
||||
return loader.NewTypedSettings(config), nil
|
||||
}
|
||||
|
||||
var (
|
||||
configLoader = NewJSONConfigLoader(
|
||||
ConfigCreatorCache{
|
||||
"none": func() interface{} { return new(NoneResponse) },
|
||||
"http": func() interface{} { return new(HttpResponse) },
|
||||
},
|
||||
"type",
|
||||
"")
|
||||
)
|
34
tools/conf/blackhole_test.go
Normal file
34
tools/conf/blackhole_test.go
Normal file
@ -0,0 +1,34 @@
|
||||
package conf_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"v2ray.com/core/proxy/blackhole"
|
||||
"v2ray.com/core/testing/assert"
|
||||
. "v2ray.com/core/tools/conf"
|
||||
)
|
||||
|
||||
func TestHTTPResponseJSON(t *testing.T) {
|
||||
assert := assert.On(t)
|
||||
|
||||
rawJson := `{
|
||||
"response": {
|
||||
"type": "http"
|
||||
}
|
||||
}`
|
||||
rawConfig := new(BlackholeConfig)
|
||||
err := json.Unmarshal([]byte(rawJson), rawConfig)
|
||||
assert.Error(err).IsNil()
|
||||
|
||||
ts, err := rawConfig.Build()
|
||||
assert.Error(err).IsNil()
|
||||
iConfig, err := ts.GetInstance()
|
||||
assert.Error(err).IsNil()
|
||||
config := iConfig.(*blackhole.Config)
|
||||
response, err := config.GetInternalResponse()
|
||||
assert.Error(err).IsNil()
|
||||
|
||||
_, ok := response.(*blackhole.HTTPResponse)
|
||||
assert.Bool(ok).IsTrue()
|
||||
}
|
9
tools/conf/builable.go
Normal file
9
tools/conf/builable.go
Normal file
@ -0,0 +1,9 @@
|
||||
package conf
|
||||
|
||||
import (
|
||||
"v2ray.com/core/common/loader"
|
||||
)
|
||||
|
||||
type Buildable interface {
|
||||
Build() (*loader.TypedSettings, error)
|
||||
}
|
@ -5,9 +5,38 @@ import (
|
||||
"errors"
|
||||
|
||||
"strings"
|
||||
"v2ray.com/core/common/log"
|
||||
v2net "v2ray.com/core/common/net"
|
||||
"v2ray.com/core/common/protocol"
|
||||
)
|
||||
|
||||
type StringList []string
|
||||
|
||||
func NewStringList(raw []string) *StringList {
|
||||
list := StringList(raw)
|
||||
return &list
|
||||
}
|
||||
|
||||
func (this StringList) Len() int {
|
||||
return len(this)
|
||||
}
|
||||
|
||||
func (this *StringList) UnmarshalJSON(data []byte) error {
|
||||
var strarray []string
|
||||
if err := json.Unmarshal(data, &strarray); err == nil {
|
||||
*this = *NewStringList(strarray)
|
||||
return nil
|
||||
}
|
||||
|
||||
var rawstr string
|
||||
if err := json.Unmarshal(data, &rawstr); err == nil {
|
||||
strlist := strings.Split(rawstr, ",")
|
||||
*this = *NewStringList(strlist)
|
||||
return nil
|
||||
}
|
||||
return errors.New("Unknown format of a string list: " + string(data))
|
||||
}
|
||||
|
||||
type Address |