Skip to content

Conversation

@1oca1h0st
Copy link

修复了新版API在更新隧道时,由于仅更新隧道名字导致的409错误

问题描述:
当编辑隧道配置时,如果仅更新隧道名字,当走到updateInstance的函数中时,CORE会返回409错误导致名字更新失败

解决方案:

  • 在更新实例时,取出对应实例原有在库中的commandLine,与传入的信息拼接后的commandLine比较
  • 新增 normalizeCommandLine 函数,将 URL 查询参数按字母顺序排序后再进行比较
  • 在比较新旧 commandLine 之前,先对两者进行规范化处理
  • 添加了错误处理,如果规范化失败会回退到原始字符串比较
  • 改进了日志输出,将配置变化的日志从 Error 级别改为 Info 级别
  • 当commandLine没有变化时,应当进行PATCH功能仅修改实例的名称

影响范围:

  • 仅影响隧道编辑功能的判断逻辑
  • 确保参数顺序不影响配置比较结果
  • 避免不必要的隧道实例更新操作

修复了在更新隧道时,由于 URL 参数顺序不同导致的误判问题。

**问题描述:**
当编辑隧道配置时,即使参数内容相同但顺序不同(如 `log=info&mode=2&tls=1` vs `log=info&tls=1&mode=2`),系统会错误地认为配置发生了变化,导致触发不必要的实例更新操作。

**解决方案:**
- 新增 `normalizeCommandLine` 函数,将 URL 查询参数按字母顺序排序后再进行比较
- 在比较新旧 commandLine 之前,先对两者进行规范化处理
- 添加了错误处理,如果规范化失败会回退到原始字符串比较
- 改进了日志输出,将配置变化的日志从 Error 级别改为 Info 级别

**影响范围:**
- 仅影响隧道编辑功能的判断逻辑
- 确保参数顺序不影响配置比较结果
- 避免不必要的隧道实例更新操作

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@yosebyte yosebyte requested a review from Copilot October 16, 2025 10:44
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Purpose: Prevent erroneous 409 conflicts when updating a tunnel name without changing its parameters by distinguishing pure name changes from real instance configuration updates through normalized commandLine comparison.

  • Add normalizeCommandLine to order query parameters deterministically before comparison
  • Introduce conditional path to call RenameInstance instead of UpdateInstance when only the name changed
  • Adjust logging levels and add fallback logic when normalization fails

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines 62 to 80
// 获取所有的参数键并排序
keys := make([]string, 0, len(values))
for k := range values {
keys = append(keys, k)
}
sort.Strings(keys)

// 按排序后的顺序重建查询参数
params := make([]string, 0, len(keys))
for _, k := range keys {
for _, v := range values[k] {
params = append(params, fmt.Sprintf("%s=%s", k, v))
}
}

// 重建完整的 commandLine
if len(params) > 0 {
return base + "?" + strings.Join(params, "&"), nil
}
Copy link

Copilot AI Oct 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Manual reconstruction of the query string does not perform URL encoding and can change semantics (e.g., spaces, &, =, +, % in keys/values) compared to the original; it may also introduce a trailing = for naked keys, leading to false inequality or broken commands. Use values.Encode() (which sorts keys and applies proper escaping) or apply url.QueryEscape to both key and value: params = append(params, fmt.Sprintf("%s=%s", url.QueryEscape(k), url.QueryEscape(v))). Example replacement: return base + "?" + values.Encode(), nil.

Suggested change
// 获取所有的参数键并排序
keys := make([]string, 0, len(values))
for k := range values {
keys = append(keys, k)
}
sort.Strings(keys)
// 按排序后的顺序重建查询参数
params := make([]string, 0, len(keys))
for _, k := range keys {
for _, v := range values[k] {
params = append(params, fmt.Sprintf("%s=%s", k, v))
}
}
// 重建完整的 commandLine
if len(params) > 0 {
return base + "?" + strings.Join(params, "&"), nil
}
// 使用标准库方法对参数排序并进行URL编码
encoded := values.Encode()
if encoded != "" {
return base + "?" + encoded, nil
}

Copilot uses AI. Check for mistakes.
优化了 normalizeCommandLine 函数,通过使用 Encode() 方法重建查询参数,自动处理参数排序和编码,简化了代码逻辑。此更改确保了在比较 URL 参数时的准确性和一致性,进一步提升了隧道编辑功能的稳定性。
@1oca1h0st
Copy link
Author

@yosebyte 已经根据建议修复,请review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant