| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- package conf
- import (
- "encoding/json"
- "github.com/xtls/xray-core/common/errors"
- "github.com/xtls/xray-core/common/protocol"
- "github.com/xtls/xray-core/common/serial"
- "github.com/xtls/xray-core/proxy/http"
- "google.golang.org/protobuf/proto"
- )
- type HTTPAccount struct {
- Username string `json:"user"`
- Password string `json:"pass"`
- }
- func (v *HTTPAccount) Build() *http.Account {
- return &http.Account{
- Username: v.Username,
- Password: v.Password,
- }
- }
- type HTTPServerConfig struct {
- Accounts []*HTTPAccount `json:"accounts"`
- Transparent bool `json:"allowTransparent"`
- UserLevel uint32 `json:"userLevel"`
- }
- func (c *HTTPServerConfig) Build() (proto.Message, error) {
- config := &http.ServerConfig{
- AllowTransparent: c.Transparent,
- UserLevel: c.UserLevel,
- }
- if len(c.Accounts) > 0 {
- config.Accounts = make(map[string]string)
- for _, account := range c.Accounts {
- config.Accounts[account.Username] = account.Password
- }
- }
- return config, nil
- }
- type HTTPRemoteConfig struct {
- Address *Address `json:"address"`
- Port uint16 `json:"port"`
- Users []json.RawMessage `json:"users"`
- }
- type HTTPClientConfig struct {
- Address *Address `json:"address"`
- Port uint16 `json:"port"`
- Level uint32 `json:"level"`
- Email string `json:"email"`
- Username string `json:"user"`
- Password string `json:"pass"`
- Servers []*HTTPRemoteConfig `json:"servers"`
- Headers map[string]string `json:"headers"`
- }
- func (v *HTTPClientConfig) Build() (proto.Message, error) {
- config := new(http.ClientConfig)
- if v.Address != nil {
- v.Servers = []*HTTPRemoteConfig{
- {
- Address: v.Address,
- Port: v.Port,
- },
- }
- if len(v.Username) > 0 {
- v.Servers[0].Users = []json.RawMessage{{}}
- }
- }
- if len(v.Servers) != 1 {
- return nil, errors.New(`HTTP settings: "servers" should have one and only one member. Multiple endpoints in "servers" should use multiple HTTP outbounds and routing balancer instead`)
- }
- for _, serverConfig := range v.Servers {
- if len(serverConfig.Users) > 1 {
- return nil, errors.New(`HTTP servers: "users" should have one member at most. Multiple members in "users" should use multiple HTTP outbounds and routing balancer instead`)
- }
- server := &protocol.ServerEndpoint{
- Address: serverConfig.Address.Build(),
- Port: uint32(serverConfig.Port),
- }
- for _, rawUser := range serverConfig.Users {
- user := new(protocol.User)
- if v.Address != nil {
- user.Level = v.Level
- user.Email = v.Email
- } else {
- if err := json.Unmarshal(rawUser, user); err != nil {
- return nil, errors.New("failed to parse HTTP user").Base(err).AtError()
- }
- }
- account := new(HTTPAccount)
- if v.Address != nil {
- account.Username = v.Username
- account.Password = v.Password
- } else {
- if err := json.Unmarshal(rawUser, account); err != nil {
- return nil, errors.New("failed to parse HTTP account").Base(err).AtError()
- }
- }
- user.Account = serial.ToTypedMessage(account.Build())
- server.User = user
- break
- }
- config.Server = server
- break
- }
- config.Header = make([]*http.Header, 0, 32)
- for key, value := range v.Headers {
- config.Header = append(config.Header, &http.Header{
- Key: key,
- Value: value,
- })
- }
- return config, nil
- }
|