[优化] 添加 WebSocket 连接升级映射,更新主配置模板和测试用例

This commit is contained in:
ryan
2026-03-15 13:57:32 +08:00
parent b1be887287
commit 4024c85a0c
3 changed files with 39 additions and 5 deletions
+1 -1
View File
@@ -101,7 +101,7 @@ events {
http {
include mime.types;
default_type application/octet-stream;
log_format atsflare_json escape=json '{"ts":"$time_iso8601","host":"$host","path":"$request_uri","remote_addr":"$remote_addr","status":$status,"request_time":$request_time,"bytes_sent":$body_bytes_sent,"request_length":$request_length}';
{{OpenRestyWebsocketConnectionMap}} log_format atsflare_json escape=json '{"ts":"$time_iso8601","host":"$host","path":"$request_uri","remote_addr":"$remote_addr","status":$status,"request_time":$request_time,"bytes_sent":$body_bytes_sent,"request_length":$request_length}';
access_log {{OpenRestyAccessLogPath}} atsflare_json;
sendfile on;
tcp_nopush on;
+24 -2
View File
@@ -121,7 +121,7 @@ const (
nginxAccessLogPlaceholder = "__ATSF_ACCESS_LOG__"
nginxLuaDirPlaceholder = "__ATSF_LUA_DIR__"
nginxObservabilityListenPlaceholder = "__ATSF_OBSERVABILITY_LISTEN__"
nginxObservabilityPortPlaceholder = "__ATSF_OBSERVABILITY_PORT__"
openRestyWebsocketConnectionMapTag = "{{OpenRestyWebsocketConnectionMap}}"
)
var requiredMainConfigTemplatePlaceholders = []string{
@@ -643,11 +643,13 @@ func defaultOpenRestyMainConfigTemplate() string {
}
func renderMainConfigTemplate(templateText string, cfg openRestyConfigSnapshot) string {
templateText = ensureWebsocketConnectionMapPlaceholder(templateText)
replacer := strings.NewReplacer(
"{{OpenRestyWorkerProcesses}}", cfg.WorkerProcesses,
"{{OpenRestyWorkerConnections}}", fmt.Sprintf("%d", cfg.WorkerConnections),
"{{OpenRestyWorkerRlimitNofile}}", fmt.Sprintf("%d", cfg.WorkerRlimitNofile),
"{{OpenRestyAccessLogPath}}", nginxAccessLogPlaceholder,
openRestyWebsocketConnectionMapTag, renderWebsocketConnectionMap(cfg.WebsocketEnabled),
"{{OpenRestyEventsUseDirective}}", renderTemplateDirective(cfg.EventsUse != "", fmt.Sprintf("use %s;", cfg.EventsUse)),
"{{OpenRestyEventsMultiAcceptDirective}}", renderTemplateDirective(cfg.EventsMultiAcceptEnabled, "multi_accept on;"),
"{{OpenRestyKeepaliveTimeout}}", fmt.Sprintf("%d", cfg.KeepaliveTimeout),
@@ -681,6 +683,26 @@ func renderTemplateDirective(enabled bool, statement string) string {
return fmt.Sprintf(" %s\n", statement)
}
func ensureWebsocketConnectionMapPlaceholder(templateText string) string {
if strings.Contains(templateText, openRestyWebsocketConnectionMapTag) {
return templateText
}
return strings.Replace(templateText, "{{OpenRestyRouteConfigInclude}}", openRestyWebsocketConnectionMapTag+" include {{OpenRestyRouteConfigInclude}}", 1)
}
func renderWebsocketConnectionMap(enabled bool) string {
if !enabled {
return ""
}
return stringsJoinLines(
" map $http_upgrade $connection_upgrade {",
" default upgrade;",
" '' close;",
" }",
"",
)
}
func renderOpenRestyCacheTemplateBlock(cfg openRestyConfigSnapshot) string {
lines := make([]string, 0, 8)
if !cfg.CacheEnabled {
@@ -769,7 +791,7 @@ func renderProxyHeaderBlock(customHeaders []ProxyRouteCustomHeaderInput) string
if common.OpenRestyWebsocketEnabled {
builder.WriteString(" proxy_http_version 1.1;\n")
builder.WriteString(" proxy_set_header Upgrade $http_upgrade;\n")
builder.WriteString(" proxy_set_header Connection $http_connection;\n")
builder.WriteString(" proxy_set_header Connection $connection_upgrade;\n")
}
for _, header := range customHeaders {
builder.WriteString(fmt.Sprintf(" proxy_set_header %s %s;\n", header.Key, quoteNginxHeaderValue(header.Value)))
+14 -2
View File
@@ -63,6 +63,9 @@ func TestCreateTLSCertificateAndRenderHTTPSConfig(t *testing.T) {
if !strings.Contains(result.Version.MainConfig, "listen __ATSF_OBSERVABILITY_LISTEN__;") {
t.Fatal("expected main config to include managed openresty observability listen placeholder")
}
if !strings.Contains(result.Version.MainConfig, "map $http_upgrade $connection_upgrade {") {
t.Fatal("expected main config to include websocket connection upgrade map")
}
if strings.Contains(result.Version.MainConfig, "allow 127.0.0.1;") {
t.Fatal("expected main config to avoid hard-coded allow rules on observability server")
}
@@ -132,7 +135,7 @@ func TestPublishConfigVersionRendersCustomHeaders(t *testing.T) {
if !strings.Contains(result.Version.RenderedConfig, "proxy_set_header Upgrade $http_upgrade;") {
t.Fatal("expected rendered config to forward websocket upgrade header")
}
if !strings.Contains(result.Version.RenderedConfig, "proxy_set_header Connection $http_connection;") {
if !strings.Contains(result.Version.RenderedConfig, "proxy_set_header Connection $connection_upgrade;") {
t.Fatal("expected rendered config to forward websocket connection header")
}
}
@@ -162,9 +165,12 @@ func TestPreviewConfigVersionCanDisableWebsocketHeaders(t *testing.T) {
if strings.Contains(preview.RenderedConfig, "proxy_set_header Upgrade $http_upgrade;") {
t.Fatal("expected preview config to omit websocket upgrade header when disabled")
}
if strings.Contains(preview.RenderedConfig, "proxy_set_header Connection $http_connection;") {
if strings.Contains(preview.RenderedConfig, "proxy_set_header Connection $connection_upgrade;") {
t.Fatal("expected preview config to omit websocket connection header when disabled")
}
if strings.Contains(preview.MainConfig, "map $http_upgrade $connection_upgrade {") {
t.Fatal("expected preview main config to omit websocket connection map when disabled")
}
}
func TestPreviewAndDiffConfigVersion(t *testing.T) {
@@ -326,6 +332,9 @@ func TestCreateTLSCertificateRejectsInvalidPEM(t *testing.T) {
func TestOpenRestyMainConfigTemplateRenderAndValidate(t *testing.T) {
setupServiceTestDB(t)
if err := model.UpdateOption("OpenRestyWebsocketEnabled", "true"); err != nil {
t.Fatalf("UpdateOption OpenRestyWebsocketEnabled failed: %v", err)
}
customTemplate := strings.ReplaceAll(
common.OpenRestyMainConfigTemplate,
@@ -355,6 +364,9 @@ func TestOpenRestyMainConfigTemplateRenderAndValidate(t *testing.T) {
if !strings.Contains(preview.MainConfig, "access_log __ATSF_ACCESS_LOG__ atsflare_json;") {
t.Fatal("expected preview main config to preserve managed access log placeholder")
}
if !strings.Contains(preview.MainConfig, "map $http_upgrade $connection_upgrade {") {
t.Fatal("expected preview main config to include websocket connection map")
}
invalidTemplate := strings.ReplaceAll(
common.OpenRestyMainConfigTemplate,