瀏覽代碼

json config for http header

Darien Raymond 9 年之前
父節點
當前提交
3d167a6855
共有 2 個文件被更改,包括 163 次插入1 次删除
  1. 145 0
      tools/conf/transport_authenticators.go
  2. 18 1
      tools/conf/transport_internet.go

+ 145 - 0
tools/conf/transport_authenticators.go

@@ -1,7 +1,12 @@
 package conf
 
 import (
+	"encoding/json"
+
+	"errors"
+	"strings"
 	"v2ray.com/core/common/loader"
+	"v2ray.com/core/transport/internet/authenticators/http"
 	"v2ray.com/core/transport/internet/authenticators/noop"
 	"v2ray.com/core/transport/internet/authenticators/srtp"
 	"v2ray.com/core/transport/internet/authenticators/utp"
@@ -24,3 +29,143 @@ type UTPAuthenticator struct{}
 func (UTPAuthenticator) Build() (*loader.TypedSettings, error) {
 	return loader.NewTypedSettings(new(utp.Config)), nil
 }
+
+type HTTPAuthenticatorHeader struct {
+	Name  string      `json:"name"`
+	Value *StringList `json:"value"`
+}
+
+type HTTPAuthenticatorRequest struct {
+	Version *string                   `json:"version"`
+	Method  *string                   `json:"method"`
+	Path    *StringList               `json:"path"`
+	Headers []HTTPAuthenticatorHeader `json:"headers"`
+}
+
+func (this *HTTPAuthenticatorRequest) Build() (*http.RequestConfig, error) {
+	config := &http.RequestConfig{
+		Uri: []string{"/"},
+		Header: []*http.Header{
+			{
+				Name:  "Host",
+				Value: []string{"www.baidu.com", "www.bing.com"},
+			},
+		},
+	}
+
+	if this.Version != nil {
+		config.Version = &http.Version{Value: *this.Version}
+	}
+
+	if this.Method != nil {
+		config.Method = &http.Method{Value: *this.Method}
+	}
+
+	if this.Path != nil && this.Path.Len() > 0 {
+		config.Uri = append([]string(nil), (*this.Path)...)
+	}
+
+	if len(this.Headers) > 0 {
+		config.Header = make([]*http.Header, len(this.Headers))
+		for idx, header := range this.Headers {
+			config.Header[idx] = &http.Header{
+				Name:  header.Name,
+				Value: append([]string(nil), (*header.Value)...),
+			}
+		}
+	}
+
+	return config, nil
+}
+
+type HTTPAuthenticatorResponse struct {
+	Version *string                   `json:"version"`
+	Status  *string                   `json:"status"`
+	Reason  *string                   `json:"reason"`
+	Headers []HTTPAuthenticatorHeader `json:"headers"`
+}
+
+func (this *HTTPAuthenticatorResponse) Build() (*http.ResponseConfig, error) {
+	config := &http.ResponseConfig{
+		Header: []*http.Header{
+			{
+				Name:  "Content-Type",
+				Value: []string{"application/octet-stream", "video/mpeg"},
+			},
+			{
+				Name:  "Transfer-Encoding",
+				Value: []string{"chunked"},
+			},
+		},
+	}
+
+	if this.Version != nil {
+		config.Version = &http.Version{Value: *this.Version}
+	}
+
+	if this.Status != nil || this.Reason != nil {
+		config.Status = http.Status{
+			Code:   "200",
+			Reason: "OK",
+		}
+		if this.Status != nil {
+			config.Status.Code = *this.Status
+		}
+		if this.Reason != nil {
+			config.Status.Reason = *this.Reason
+		}
+	}
+
+	if len(this.Headers) > 0 {
+		config.Header = make([]*http.Header, len(this.Headers))
+		for idx, header := range this.Headers {
+			config.Header[idx] = &http.Header{
+				Name:  header.Name,
+				Value: append([]string(nil), (*header.Value)...),
+			}
+		}
+	}
+
+	return config, nil
+}
+
+type HTTPAuthenticator struct {
+	Request  *HTTPAuthenticatorRequest `json:"request"`
+	Response json.RawMessage           `json:"response"`
+}
+
+func (this *HTTPAuthenticator) Build() (*loader.TypedSettings, error) {
+	config := new(http.Config)
+	if this.Request != nil {
+		requestConfig, err := this.Request.Build()
+		if err != nil {
+			return nil, err
+		}
+		config.Request = requestConfig
+	}
+
+	if len(this.Response) > 0 {
+		var text string
+		parsed := false
+		if err := json.Unmarshal(this.Response, &text); err == nil {
+			if strings.ToLower(text) != "disabled" {
+				return nil, errors.New("Unknown HTTP header settings: " + text)
+			}
+			parsed = true
+		}
+
+		if !parsed {
+			var response HTTPAuthenticatorResponse
+			if err := json.Unmarshal(this.Response, &response); err != nil {
+				return nil, errors.New("Failed to parse HTTP header response.")
+			}
+			responseConfig, err := response.Build()
+			if err != nil {
+				return nil, err
+			}
+			config.Response = responseConfig
+		}
+	}
+
+	return loader.NewTypedSettings(config), nil
+}

+ 18 - 1
tools/conf/transport_internet.go

@@ -22,6 +22,10 @@ var (
 		"srtp": func() interface{} { return new(SRTPAuthenticator) },
 		"utp":  func() interface{} { return new(UTPAuthenticator) },
 	}, "type", "")
+
+	tcpHeaderLoader = NewJSONConfigLoader(ConfigCreatorCache{
+		"http": func() interface{} { return new(HTTPAuthenticator) },
+	}, "type", "")
 )
 
 type KCPConfig struct {
@@ -93,7 +97,8 @@ func (this *KCPConfig) Build() (*loader.TypedSettings, error) {
 }
 
 type TCPConfig struct {
-	ConnectionReuse *bool `json:"connectionReuse"`
+	ConnectionReuse *bool           `json:"connectionReuse"`
+	HeaderConfig    json.RawMessage `json:"header"`
 }
 
 func (this *TCPConfig) Build() (*loader.TypedSettings, error) {
@@ -103,6 +108,18 @@ func (this *TCPConfig) Build() (*loader.TypedSettings, error) {
 			Enable: *this.ConnectionReuse,
 		}
 	}
+	if len(this.HeaderConfig) > 0 {
+		headerConfig, _, err := tcpHeaderLoader.Load(this.HeaderConfig)
+		if err != nil {
+			return nil, errors.New("TCP|Config: Failed to parse header config: " + err.Error())
+		}
+		ts, err := headerConfig.(Buildable).Build()
+		if err != nil {
+			return nil, errors.New("Failed to get TCP authenticator config: " + err.Error())
+		}
+		config.HeaderSettings = ts
+	}
+
 	return loader.NewTypedSettings(config), nil
 }