fix(converter): 修复 nginx 配置解析空字符串和 upstream URL

- 解析器正确处理空引号字符串 "",使用标记区分空字符串和特殊字符
- upstream server URL 自动添加 http:// 前缀以满足 lolly 配置验证
- proxy_set_header 正确处理空字符串值(如 Connection "")

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
xfy 2026-04-27 11:27:32 +08:00
parent c18ce613b3
commit b290cea0f6
3 changed files with 28 additions and 9 deletions

View File

@ -167,7 +167,12 @@ func convertUpstreamServer(d *Directive) config.ProxyTarget {
target := config.ProxyTarget{}
if len(d.Args) > 0 {
target.URL = d.Args[0]
url := d.Args[0]
// Add http:// prefix if no scheme present (nginx upstream servers don't have schemes)
if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") {
url = "http://" + url
}
target.URL = url
}
for _, arg := range d.Args[1:] {
@ -619,7 +624,12 @@ func convertProxyDirectives(directives []Directive, proxy *config.ProxyConfig, u
if proxy.Headers.SetRequest == nil {
proxy.Headers.SetRequest = make(map[string]string)
}
proxy.Headers.SetRequest[d.Args[0]] = mapVariable(d.Args[1], result, d)
value := mapVariable(d.Args[1], result, d)
// Convert the empty string marker back to actual empty string
if value == `""` {
value = ""
}
proxy.Headers.SetRequest[d.Args[0]] = value
}
case "proxy_hide_header":
if len(d.Args) > 0 {

View File

@ -159,8 +159,8 @@ http {
t.Fatalf("expected 3 targets, got %d", len(p.Targets))
}
if p.Targets[0].URL != "10.0.0.1:8080" {
t.Errorf("target[0] URL = %s, want 10.0.0.1:8080", p.Targets[0].URL)
if p.Targets[0].URL != "http://10.0.0.1:8080" {
t.Errorf("target[0] URL = %s, want http://10.0.0.1:8080", p.Targets[0].URL)
}
if p.Targets[0].Weight != 3 {
t.Errorf("target[0] Weight = %d, want 3", p.Targets[0].Weight)
@ -1244,11 +1244,11 @@ http {
if len(p.Targets) != 2 {
t.Fatalf("expected 2 targets from upstream inside http block, got %d", len(p.Targets))
}
if p.Targets[0].URL != "10.0.0.1:8080" {
t.Errorf("target[0] URL = %s, want 10.0.0.1:8080", p.Targets[0].URL)
if p.Targets[0].URL != "http://10.0.0.1:8080" {
t.Errorf("target[0] URL = %s, want http://10.0.0.1:8080", p.Targets[0].URL)
}
if p.Targets[1].URL != "10.0.0.2:8080" {
t.Errorf("target[1] URL = %s, want 10.0.0.2:8080", p.Targets[1].URL)
if p.Targets[1].URL != "http://10.0.0.2:8080" {
t.Errorf("target[1] URL = %s, want http://10.0.0.2:8080", p.Targets[1].URL)
}
}

View File

@ -280,7 +280,16 @@ func (p *parser) readToken() (string, error) {
ch := p.input[p.pos]
if ch == '"' || ch == '\'' {
return p.readQuotedString(ch)
token, err := p.readQuotedString(ch)
if err != nil {
return "", err
}
// Return a special marker for empty quoted strings to distinguish
// from the empty string returned when encountering special chars.
if token == "" {
return `""`, nil
}
return token, nil
}
if ch == '{' || ch == '}' || ch == ';' {