Skip to content

Commit

Permalink
Add SplitHTTP Transport (XTLS#3412)
Browse files Browse the repository at this point in the history
  • Loading branch information
mmmray authored and leninalive committed Oct 29, 2024
1 parent 4aba2b5 commit 65b7a1a
Show file tree
Hide file tree
Showing 16 changed files with 1,288 additions and 19 deletions.
12 changes: 12 additions & 0 deletions infra/conf/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type TransportConfig struct {
GRPCConfig *GRPCConfig `json:"grpcSettings"`
GUNConfig *GRPCConfig `json:"gunSettings"`
HTTPUPGRADEConfig *HttpUpgradeConfig `json:"httpupgradeSettings"`
SplitHTTPConfig *SplitHTTPConfig `json:"splithttpSettings"`
}

// Build implements Buildable.
Expand Down Expand Up @@ -113,5 +114,16 @@ func (c *TransportConfig) Build() (*global.Config, error) {
})
}

if c.SplitHTTPConfig != nil {
shs, err := c.SplitHTTPConfig.Build()
if err != nil {
return nil, newError("failed to build SplitHTTP config").Base(err)
}
config.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{
ProtocolName: "splithttp",
Settings: serial.ToTypedMessage(shs),
})
}

return config, nil
}
42 changes: 42 additions & 0 deletions infra/conf/transport_internet.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/amnezia-vpn/amnezia-xray-core/transport/internet/kcp"
"github.com/amnezia-vpn/amnezia-xray-core/transport/internet/quic"
"github.com/amnezia-vpn/amnezia-xray-core/transport/internet/reality"
"github.com/amnezia-vpn/amnezia-xray-core/transport/internet/splithttp"
"github.com/amnezia-vpn/amnezia-xray-core/transport/internet/tcp"
"github.com/amnezia-vpn/amnezia-xray-core/transport/internet/tls"
"github.com/amnezia-vpn/amnezia-xray-core/transport/internet/websocket"
Expand Down Expand Up @@ -223,6 +224,34 @@ func (c *HttpUpgradeConfig) Build() (proto.Message, error) {
return config, nil
}

type SplitHTTPConfig struct {
Host string `json:"host"`
Path string `json:"path"`
Headers map[string]string `json:"headers"`
MaxConcurrentUploads int32 `json:"maxConcurrentUploads"`
MaxUploadSize int32 `json:"maxUploadSize"`
}

// Build implements Buildable.
func (c *SplitHTTPConfig) Build() (proto.Message, error) {
// If http host is not set in the Host field, but in headers field, we add it to Host Field here.
// If we don't do that, http host will be overwritten as address.
// Host priority: Host field > headers field > address.
if c.Host == "" && c.Headers["host"] != "" {
c.Host = c.Headers["host"]
} else if c.Host == "" && c.Headers["Host"] != "" {
c.Host = c.Headers["Host"]
}
config := &splithttp.Config{
Path: c.Path,
Host: c.Host,
Header: c.Headers,
MaxConcurrentUploads: c.MaxConcurrentUploads,
MaxUploadSize: c.MaxUploadSize,
}
return config, nil
}

type HTTPConfig struct {
Host *StringList `json:"host"`
Path string `json:"path"`
Expand Down Expand Up @@ -648,6 +677,8 @@ func (p TransportProtocol) Build() (string, error) {
return "grpc", nil
case "httpupgrade":
return "httpupgrade", nil
case "splithttp":
return "splithttp", nil
default:
return "", newError("Config: unknown transport protocol: ", p)
}
Expand Down Expand Up @@ -762,6 +793,7 @@ type StreamConfig struct {
GRPCConfig *GRPCConfig `json:"grpcSettings"`
GUNConfig *GRPCConfig `json:"gunSettings"`
HTTPUPGRADESettings *HttpUpgradeConfig `json:"httpupgradeSettings"`
SplitHTTPSettings *SplitHTTPConfig `json:"splithttpSettings"`
}

// Build implements Buildable.
Expand Down Expand Up @@ -892,6 +924,16 @@ func (c *StreamConfig) Build() (*internet.StreamConfig, error) {
Settings: serial.ToTypedMessage(hs),
})
}
if c.SplitHTTPSettings != nil {
hs, err := c.SplitHTTPSettings.Build()
if err != nil {
return nil, newError("Failed to build SplitHTTP config.").Base(err)
}
config.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{
ProtocolName: "splithttp",
Settings: serial.ToTypedMessage(hs),
})
}
if c.SocketSettings != nil {
ss, err := c.SocketSettings.Build()
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions infra/conf/xray.go
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,9 @@ func applyTransportConfig(s *StreamConfig, t *TransportConfig) {
if s.HTTPUPGRADESettings == nil {
s.HTTPUPGRADESettings = t.HTTPUPGRADEConfig
}
if s.SplitHTTPSettings == nil {
s.SplitHTTPSettings = t.SplitHTTPConfig
}
}

// Build implements Buildable.
Expand Down
1 change: 1 addition & 0 deletions main/distro/all/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import (
_ "github.com/amnezia-vpn/amnezia-xray-core/transport/internet/kcp"
_ "github.com/amnezia-vpn/amnezia-xray-core/transport/internet/quic"
_ "github.com/amnezia-vpn/amnezia-xray-core/transport/internet/reality"
_ "github.com/amnezia-vpn/amnezia-xray-core/transport/internet/splithttp"
_ "github.com/amnezia-vpn/amnezia-xray-core/transport/internet/tcp"
_ "github.com/amnezia-vpn/amnezia-xray-core/transport/internet/tls"
_ "github.com/amnezia-vpn/amnezia-xray-core/transport/internet/udp"
Expand Down
42 changes: 23 additions & 19 deletions transport/internet/config.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions transport/internet/config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ enum TransportProtocol {
HTTP = 4;
DomainSocket = 5;
HTTPUpgrade = 6;
SplitHTTP = 7;
}

enum DomainStrategy {
Expand Down
52 changes: 52 additions & 0 deletions transport/internet/splithttp/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package splithttp

import (
"net/http"

"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/transport/internet"
)

func (c *Config) GetNormalizedPath() string {
path := c.Path
if path == "" {
path = "/"
}
if path[0] != '/' {
path = "/" + path
}
if path[len(path)-1] != '/' {
path = path + "/"
}
return path
}

func (c *Config) GetRequestHeader() http.Header {
header := http.Header{}
for k, v := range c.Header {
header.Add(k, v)
}
return header
}

func (c *Config) GetNormalizedMaxConcurrentUploads() int32 {
if c.MaxConcurrentUploads == 0 {
return 10
}

return c.MaxConcurrentUploads
}

func (c *Config) GetNormalizedMaxUploadSize() int32 {
if c.MaxUploadSize == 0 {
return 1000000
}

return c.MaxUploadSize
}

func init() {
common.Must(internet.RegisterProtocolConfigCreator(protocolName, func() interface{} {
return new(Config)
}))
}
Loading

0 comments on commit 65b7a1a

Please sign in to comment.