4940278ea5
Deploy Server / deploy-server (push) Successful in 2m55s
Deploy Site / deploy-site (push) Successful in 2m41s
Deploy Client / build-windows (push) Successful in 1m47s
Deploy Client / build-android (push) Successful in 7m39s
Deploy Client / build-macos (push) Successful in 3m40s
Deploy Client / build-ios (push) Successful in 4m48s
Deploy Client / release-deploy (push) Successful in 2m25s
原独立子域 app.yanmeiai.com → 主站子路径 /user/(用户选停用旧域名): - 域名配置化(去硬编码):客户端 kWebUserCenterBaseUrl 收进 api_config.dart (dart-define 可覆盖);官网 site.ts、服务端 CORS_ORIGINS 本就是配置 - 用户中心 next.config basePath=/user;layout.tsx 的 /colors_and_type.css 手动 拼 basePath(public 根绝对资源不自动加前缀,否则 404) - CI 合并部署:compile-site + compile-usercenter + combine-site(用户中心并入 dist/user/ + _headers 按 /user/* 分域:官网严格 CSP,用户中心 unsafe-inline+ connect-src https)→ 单次部署 pangolin-site;删独立 pangolin-usercenter 部署 - 服务端 CORS 默认 origin app.yanmeiai.com → pangolin.yanmeiai.com(+ 测试) - 客户端 web_launch 走新址 → 随 client-v1.0.62;go test CORS 过、flutter analyze 净 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
48 lines
1.5 KiB
Go
48 lines
1.5 KiB
Go
package httpapi
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
)
|
|
|
|
func TestCORS(t *testing.T) {
|
|
t.Setenv("CORS_ORIGINS", "https://pangolin.yanmeiai.com")
|
|
mw := NewCORS()
|
|
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) })
|
|
h := mw(next)
|
|
|
|
// 允许的 Origin:补 Allow-Origin,普通请求继续。
|
|
r := httptest.NewRequest("POST", "/v1/auth/login", nil)
|
|
r.Header.Set("Origin", "https://pangolin.yanmeiai.com")
|
|
w := httptest.NewRecorder()
|
|
h.ServeHTTP(w, r)
|
|
if got := w.Header().Get("Access-Control-Allow-Origin"); got != "https://pangolin.yanmeiai.com" {
|
|
t.Fatalf("allowed origin: want header, got %q", got)
|
|
}
|
|
if w.Code != 200 {
|
|
t.Fatalf("non-preflight should reach next, got %d", w.Code)
|
|
}
|
|
|
|
// OPTIONS 预检:204,不落到业务。
|
|
r = httptest.NewRequest("OPTIONS", "/v1/auth/login", nil)
|
|
r.Header.Set("Origin", "https://pangolin.yanmeiai.com")
|
|
w = httptest.NewRecorder()
|
|
h.ServeHTTP(w, r)
|
|
if w.Code != http.StatusNoContent {
|
|
t.Fatalf("preflight: want 204, got %d", w.Code)
|
|
}
|
|
if w.Header().Get("Access-Control-Allow-Methods") == "" {
|
|
t.Fatalf("preflight missing Allow-Methods")
|
|
}
|
|
|
|
// 未白名单 Origin:不补 Allow-Origin。
|
|
r = httptest.NewRequest("POST", "/v1/auth/login", nil)
|
|
r.Header.Set("Origin", "https://evil.example.com")
|
|
w = httptest.NewRecorder()
|
|
h.ServeHTTP(w, r)
|
|
if got := w.Header().Get("Access-Control-Allow-Origin"); got != "" {
|
|
t.Fatalf("disallowed origin should get no header, got %q", got)
|
|
}
|
|
}
|