Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

splithttp transport #3412

Merged
merged 32 commits into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
954e6d5
splithttp transport
mmmray May 29, 2024
6d34cfc
bypass more buffering
mmmray Jun 2, 2024
dcd2847
better naming
mmmray Jun 2, 2024
9a120f9
Create splithttp_test.go
Fangliding Jun 2, 2024
3af7b2a
sync map
mmmray Jun 2, 2024
3a628c7
fix concurrency issue with splithttp vs websocket tests
mmmray Jun 3, 2024
27a29b1
try PickPort
mmmray Jun 3, 2024
344d4f4
remove dead code
mmmray Jun 3, 2024
a6822f5
reuse http client across connections
mmmray Jun 3, 2024
4ff5547
concurrent uploads, more logging and more settings
mmmray Jun 3, 2024
da45c1d
temporarily revert connection reuse
mmmray Jun 4, 2024
249510d
fix all the bugs, now and forever
mmmray Jun 4, 2024
e4cc824
get rid of mutexes in upload queue, too complicated
mmmray Jun 4, 2024
4de299d
Merge remote-tracking branch 'origin/main' into splithttp-pr
mmmray Jun 4, 2024
e5e4af4
fix incorrect automatic git merge causing compile errors
mmmray Jun 4, 2024
c51520b
Revert "temporarily revert connection reuse"
mmmray Jun 4, 2024
3eed049
some attempts to close http bodies correctly
mmmray Jun 4, 2024
630cd2d
add idle conn limits
mmmray Jun 4, 2024
450bc29
maxIdleConns cannot be set for h2
mmmray Jun 4, 2024
68975a5
drain every response body everywhere
mmmray Jun 4, 2024
3443a38
fix compilation issues
mmmray Jun 4, 2024
f3c4f6d
remove drain again
mmmray Jun 4, 2024
4cf0d9a
add http client timeout too
mmmray Jun 4, 2024
97321df
remove extra buffering, add mutex around every Write
mmmray Jun 4, 2024
cddaf53
remove useless locking, close pipe and remove maxidleconns
mmmray Jun 4, 2024
6e96b24
downloadDone with less blocking
mmmray Jun 4, 2024
c41fd89
restore BufferedWriter usage
mmmray Jun 5, 2024
a0ae157
remove timeout, the effect is unproven
mmmray Jun 5, 2024
d8ec670
constrain memory usage on server
mmmray Jun 6, 2024
8e2f6cc
uploadqueue.Read() hangs forever when the connection is already closed
mmmray Jun 7, 2024
92e30d3
split up download and upload client, to work around keepalive bug
mmmray Jun 15, 2024
c5281d4
optimized upload for http/1.1
mmmray Jun 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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/xtls/xray-core/transport/internet/kcp"
"github.com/xtls/xray-core/transport/internet/quic"
"github.com/xtls/xray-core/transport/internet/reality"
"github.com/xtls/xray-core/transport/internet/splithttp"
"github.com/xtls/xray-core/transport/internet/tcp"
"github.com/xtls/xray-core/transport/internet/tls"
"github.com/xtls/xray-core/transport/internet/websocket"
Expand Down Expand Up @@ -221,6 +222,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 @@ -646,6 +675,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 @@ -760,6 +791,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 @@ -890,6 +922,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/xtls/xray-core/transport/internet/kcp"
_ "github.com/xtls/xray-core/transport/internet/quic"
_ "github.com/xtls/xray-core/transport/internet/reality"
_ "github.com/xtls/xray-core/transport/internet/splithttp"
_ "github.com/xtls/xray-core/transport/internet/tcp"
_ "github.com/xtls/xray-core/transport/internet/tls"
_ "github.com/xtls/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