Repo .git was damaged (refs/ missing, index truncated, object store near-empty). Repaired via git init (rebuilt refs), stale index preserved as .git/index.corrupt-20260910.bak, then full worktree committed as a rollback baseline.
64 lines
2.1 KiB
Go
64 lines
2.1 KiB
Go
package route
|
|
|
|
import (
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/flamego/flamego"
|
|
|
|
"github.com/tamakyi/TamaBox/static"
|
|
)
|
|
|
|
// TestIndexNowKeyFileRoute 验证 IndexNow 密钥文件路由:能匹配含点号的路径段并返回 embed 内容,
|
|
// 同时拒绝路径穿越与非法文件名。
|
|
//
|
|
// 背景:flamego 的 Static 中间件 Prefix 为 "/static",不会接管 /index-now/,若缺少本路由,
|
|
// 请求会落到 f.NotFound 被 302 重定向到首页,搜索引擎的密钥校验必然失败。
|
|
func TestIndexNowKeyFileRoute(t *testing.T) {
|
|
f := flamego.NewWithLogger(io.Discard)
|
|
f.Get("/index-now/{key}", func(c flamego.Context) {
|
|
key := c.Param("key")
|
|
if !indexNowKeyPattern.MatchString(key) {
|
|
c.ResponseWriter().WriteHeader(http.StatusNotFound)
|
|
return
|
|
}
|
|
fs, err := static.FS.Open("index-now/" + key)
|
|
if err != nil {
|
|
c.ResponseWriter().WriteHeader(http.StatusNotFound)
|
|
return
|
|
}
|
|
defer func() { _ = fs.Close() }()
|
|
c.ResponseWriter().Header().Set("Content-Type", "text/plain; charset=utf-8")
|
|
_, _ = io.Copy(c.ResponseWriter(), fs)
|
|
})
|
|
|
|
cases := []struct {
|
|
path string
|
|
want int
|
|
wantKey bool
|
|
}{
|
|
{"/index-now/66e5e0911b0941f2ba7dbfbbd961e9be.txt", 200, true},
|
|
{"/index-now/..%2frobots.txt", 404, false}, // 路径穿越(编码斜杠)
|
|
{"/index-now/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.txt", 404, false}, // 合法格式但文件不存在
|
|
{"/index-now/../../robots.txt", 404, false}, // 路径穿越(原始)
|
|
{"/index-now/66e5e0911b0941f2ba7dbfbbd961e9be.txt.exe", 404, false}, // 后缀不符
|
|
}
|
|
for _, tc := range cases {
|
|
req := httptest.NewRequest(http.MethodGet, tc.path, nil)
|
|
w := httptest.NewRecorder()
|
|
f.ServeHTTP(w, req)
|
|
body := w.Body.String()
|
|
got := w.Code
|
|
if got != tc.want {
|
|
t.Errorf("%s -> status %d, want %d (body=%q)", tc.path, got, tc.want, body)
|
|
continue
|
|
}
|
|
if tc.wantKey && body != "66e5e0911b0941f2ba7dbfbbd961e9be" {
|
|
t.Errorf("%s -> body %q, want key content", tc.path, body)
|
|
}
|
|
t.Logf("%-56s -> %d %q", tc.path, got, body)
|
|
}
|
|
}
|