feat: add per-channel HTTP transport controls

This commit is contained in:
CaIon
2026-07-27 21:41:13 +08:00
parent b27b2b1d6f
commit e99a9bd86f
24 changed files with 1330 additions and 81 deletions
+32
View File
@@ -17,6 +17,38 @@ type ChannelSettings struct {
PassThroughBodyEnabled bool `json:"pass_through_body_enabled,omitempty"`
SystemPrompt string `json:"system_prompt,omitempty"`
SystemPromptOverride bool `json:"system_prompt_override,omitempty"`
// HTTPProtocol controls outbound HTTP version negotiation for this channel.
// Accepted values: "", "auto" (default), "http1".
HTTPProtocol string `json:"http_protocol,omitempty"`
// HTTP2ConnectionShards spreads HTTP/2 traffic across N independent transports
// (1-8). Zero/unset means 1. Ignored when HTTPProtocol is "http1".
HTTP2ConnectionShards int `json:"http2_connection_shards,omitempty"`
}
const (
HTTPProtocolAuto = "auto"
HTTPProtocolHTTP1 = "http1"
MaxHTTP2ConnectionShards = 8
)
// ValidateHTTPTransport validates save-time HTTP transport channel settings.
func (s *ChannelSettings) ValidateHTTPTransport() error {
if s == nil {
return nil
}
protocol := strings.ToLower(strings.TrimSpace(s.HTTPProtocol))
switch protocol {
case "", HTTPProtocolAuto, HTTPProtocolHTTP1:
default:
return fmt.Errorf("invalid http_protocol: %s", s.HTTPProtocol)
}
if s.HTTP2ConnectionShards < 0 || s.HTTP2ConnectionShards > MaxHTTP2ConnectionShards {
return fmt.Errorf("invalid http2_connection_shards: %d", s.HTTP2ConnectionShards)
}
if protocol == HTTPProtocolHTTP1 && s.HTTP2ConnectionShards > 1 {
return fmt.Errorf("http2_connection_shards must be 1 when http_protocol is http1")
}
return nil
}
type VertexKeyType string
+59
View File
@@ -1,6 +1,7 @@
package dto
import (
"encoding/json"
"regexp"
"testing"
@@ -519,3 +520,61 @@ func TestAdvancedCustomValidateAlphaSearchConverterPath(t *testing.T) {
})
}
}
func TestChannelSettingsHTTPTransportJSONRoundTrip(t *testing.T) {
legacy := `{"proxy":"http://127.0.0.1:8080","force_format":true}`
var settings ChannelSettings
require.NoError(t, json.Unmarshal([]byte(legacy), &settings))
assert.Equal(t, "http://127.0.0.1:8080", settings.Proxy)
assert.True(t, settings.ForceFormat)
assert.Empty(t, settings.HTTPProtocol)
assert.Zero(t, settings.HTTP2ConnectionShards)
encoded, err := json.Marshal(settings)
require.NoError(t, err)
assert.NotContains(t, string(encoded), "http_protocol")
assert.NotContains(t, string(encoded), "http2_connection_shards")
explicit := ChannelSettings{
Proxy: "socks5://127.0.0.1:1080",
HTTPProtocol: HTTPProtocolHTTP1,
HTTP2ConnectionShards: 1,
}
encoded, err = json.Marshal(explicit)
require.NoError(t, err)
assert.Contains(t, string(encoded), `"http_protocol":"http1"`)
var decoded ChannelSettings
require.NoError(t, json.Unmarshal(encoded, &decoded))
assert.Equal(t, explicit.HTTPProtocol, decoded.HTTPProtocol)
assert.Equal(t, 1, decoded.HTTP2ConnectionShards)
sharded := ChannelSettings{HTTP2ConnectionShards: 4}
encoded, err = json.Marshal(sharded)
require.NoError(t, err)
assert.Contains(t, string(encoded), `"http2_connection_shards":4`)
assert.NotContains(t, string(encoded), "http_protocol")
}
func TestChannelSettingsValidateHTTPTransport(t *testing.T) {
require.NoError(t, (&ChannelSettings{}).ValidateHTTPTransport())
require.NoError(t, (&ChannelSettings{HTTPProtocol: "AUTO"}).ValidateHTTPTransport())
require.NoError(t, (&ChannelSettings{HTTPProtocol: "http1"}).ValidateHTTPTransport())
require.NoError(t, (&ChannelSettings{HTTP2ConnectionShards: 8}).ValidateHTTPTransport())
err := (&ChannelSettings{HTTPProtocol: "http2"}).ValidateHTTPTransport()
require.Error(t, err)
assert.Contains(t, err.Error(), "http_protocol")
err = (&ChannelSettings{HTTP2ConnectionShards: -1}).ValidateHTTPTransport()
require.Error(t, err)
assert.Contains(t, err.Error(), "http2_connection_shards")
err = (&ChannelSettings{HTTP2ConnectionShards: 9}).ValidateHTTPTransport()
require.Error(t, err)
assert.Contains(t, err.Error(), "http2_connection_shards")
err = (&ChannelSettings{HTTPProtocol: "http1", HTTP2ConnectionShards: 2}).ValidateHTTPTransport()
require.Error(t, err)
assert.Contains(t, err.Error(), "http2_connection_shards")
}