mirror of
https://github.com/v2fly/v2ray-core.git
synced 2025-01-20 00:07:06 -05:00
add proto reflection based configure file parsing rule
This commit is contained in:
parent
c766b08c82
commit
690d92718b
@ -25,4 +25,9 @@ message FieldOpt{
|
|||||||
repeated string any_wants = 1;
|
repeated string any_wants = 1;
|
||||||
repeated string allowed_values = 2;
|
repeated string allowed_values = 2;
|
||||||
repeated string allowed_value_types = 3;
|
repeated string allowed_value_types = 3;
|
||||||
|
|
||||||
|
// convert_time_read_file_into read a file into another field, and clear this field during input parsing
|
||||||
|
string convert_time_read_file_into = 4;
|
||||||
|
// forbidden marks a boolean to be inaccessible to user
|
||||||
|
bool forbidden = 5;
|
||||||
}
|
}
|
90
infra/conf/protofilter/filter.go
Normal file
90
infra/conf/protofilter/filter.go
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
package protofilter
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/v2fly/v2ray-core/v4/common/platform/filesystem"
|
||||||
|
"github.com/v2fly/v2ray-core/v4/common/protoext"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
|
"google.golang.org/protobuf/reflect/protoreflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen
|
||||||
|
|
||||||
|
func FilterProtoConfig(config proto.Message) error {
|
||||||
|
messageProtoReflect := config.ProtoReflect()
|
||||||
|
return filterMessage(messageProtoReflect)
|
||||||
|
}
|
||||||
|
|
||||||
|
func filterMessage(message protoreflect.Message) error {
|
||||||
|
var err error
|
||||||
|
type fileRead struct {
|
||||||
|
filename string
|
||||||
|
field string
|
||||||
|
}
|
||||||
|
var fileReadingQueue []fileRead
|
||||||
|
message.Range(func(descriptor protoreflect.FieldDescriptor, value protoreflect.Value) bool {
|
||||||
|
v2extension, ferr := protoext.GetFieldOptions(descriptor)
|
||||||
|
if ferr != nil {
|
||||||
|
if v2extension.Forbidden {
|
||||||
|
if value.Bool() {
|
||||||
|
err = newError("a forbidden value is set ", descriptor.FullName())
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if v2extension.ConvertTimeReadFileInto != "" {
|
||||||
|
fileReadingQueue = append(fileReadingQueue, fileRead{
|
||||||
|
filename: value.String(),
|
||||||
|
field: v2extension.ConvertTimeReadFileInto,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch descriptor.Kind() {
|
||||||
|
case protoreflect.MessageKind:
|
||||||
|
if descriptor.IsMap() {
|
||||||
|
err = filterMap(value.Map())
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if descriptor.IsList() {
|
||||||
|
err = filterList(value.List())
|
||||||
|
break
|
||||||
|
}
|
||||||
|
err = filterMessage(value.Message())
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
|
for _, v := range fileReadingQueue {
|
||||||
|
file, err := filesystem.ReadFile(v.filename)
|
||||||
|
if err != nil {
|
||||||
|
return newError("unable to read file").Base(err)
|
||||||
|
}
|
||||||
|
field := message.Descriptor().Fields().ByTextName(v.field)
|
||||||
|
message.Set(field, protoreflect.ValueOf(file))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func filterMap(mapValue protoreflect.Map) error {
|
||||||
|
var err error
|
||||||
|
mapValue.Range(func(key protoreflect.MapKey, value protoreflect.Value) bool {
|
||||||
|
err = filterMessage(value.Message())
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func filterList(listValue protoreflect.List) error {
|
||||||
|
var err error
|
||||||
|
size := listValue.Len()
|
||||||
|
for i := 0; i < size; i++ {
|
||||||
|
err = filterMessage(listValue.Get(i).Message())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user