json config parser

This commit is contained in:
Darien Raymond
2016-10-17 14:35:13 +02:00
parent e866ff24a4
commit 5a311cbe08
85 changed files with 9357 additions and 9052 deletions
-6
View File
@@ -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))
}
-41
View File
@@ -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",
"")
)
-31
View File
@@ -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
View 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))
}
-32
View File
@@ -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
}
-27
View File
@@ -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
}
-22
View File
@@ -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
}
-3
View File
@@ -1,3 +0,0 @@
// +build json
package http_test
+2 -2
View File
@@ -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{
-60
View File
@@ -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
}
-34
View File
@@ -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})
}
-50
View File
@@ -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
}
-62
View File
@@ -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
}
-21
View File
@@ -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")
}
+2 -5
View File
@@ -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,
+10
View File
@@ -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
}
-85
View File
@@ -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
}
+1 -1
View File
@@ -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,
}
-73
View File
@@ -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
}
-38
View File
@@ -1,38 +0,0 @@
// +build json
package outbound_test
import (
"encoding/json"
"testing"
"v2ray.com/core/common/protocol"
"v2ray.com/core/proxy/vmess"
. "v2ray.com/core/proxy/vmess/outbound"
"v2ray.com/core/testing/assert"
)
func TestConfigTargetParsing(t *testing.T) {
assert := assert.On(t)
rawJson := `{
"vnext": [{
"address": "127.0.0.1",
"port": 80,
"users": [
{
"id": "e641f5ad-9397-41e3-bf1a-e8740dfed019",
"email": "love@v2ray.com",
"level": 255
}
]
}]
}`
config := new(Config)
err := json.Unmarshal([]byte(rawJson), &config)
assert.Error(err).IsNil()
specPB := config.Receiver[0]
spec := protocol.NewServerSpecFromPB(vmess.NewAccount, *specPB)
assert.Destination(spec.Destination()).EqualsString("tcp:127.0.0.1:80")
}