feat(web): harden server for public exposure
- hard per-traversal deadline (EXPLOREDNS_JOB_TIMEOUT, default 5m) so every job reaches a terminal state; timed-out jobs report error with any partial results instead of masquerading as complete - cap concurrent traversals (EXPLOREDNS_MAX_JOBS, default 8) returning 429 when saturated - CORS off by default (the embedded SPA is same-origin); opt in via EXPLOREDNS_CORS_ORIGIN Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
d71c7fbef2
commit
111b8bf48e
+20
-2
@@ -50,7 +50,25 @@ func TestHealth(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCORSPreflight(t *testing.T) {
|
||||
func TestCORSDisabledByDefault(t *testing.T) {
|
||||
srv := newTestServer(t)
|
||||
defer srv.Shutdown(5 * time.Second) //nolint:errcheck
|
||||
|
||||
req, _ := http.NewRequest(http.MethodGet, "http://"+srv.Addr()+"/api/health", nil)
|
||||
req.Header.Set("Origin", "http://localhost:3000")
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if got := resp.Header.Get("Access-Control-Allow-Origin"); got != "" {
|
||||
t.Fatalf("CORS should be off by default, got origin header %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCORSPreflightWithConfiguredOrigin(t *testing.T) {
|
||||
t.Setenv("EXPLOREDNS_CORS_ORIGIN", "http://localhost:3000")
|
||||
srv := newTestServer(t)
|
||||
defer srv.Shutdown(5 * time.Second) //nolint:errcheck
|
||||
|
||||
@@ -65,7 +83,7 @@ func TestCORSPreflight(t *testing.T) {
|
||||
if resp.StatusCode != http.StatusNoContent {
|
||||
t.Fatalf("want 204, got %d", resp.StatusCode)
|
||||
}
|
||||
if got := resp.Header.Get("Access-Control-Allow-Origin"); got != "*" {
|
||||
if got := resp.Header.Get("Access-Control-Allow-Origin"); got != "http://localhost:3000" {
|
||||
t.Fatalf("CORS origin header: %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user