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) } }