--- name: rate_limit_headers kind: function lang: go domain: infra version: "1.0.0" purity: pure signature: "func RateLimitHeaders(result RateLimitResult, limit int) http.Header" description: "Construye los headers IETF estandar de rate limiting (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset y Retry-After cuando se rechaza). Funcion pura, solo formatea." tags: [rate_limit, http, headers, middleware, infra] uses_functions: [] uses_types: [RateLimitResult_go_infra] returns: [] returns_optional: false error_type: "" imports: [math, net/http, strconv] params: - name: result desc: "RateLimitResult devuelto por RateLimiterCheck" - name: limit desc: "capacidad total (burst) anunciada al cliente en X-RateLimit-Limit" output: "http.Header con los 3 headers X-RateLimit-* y, cuando result.Allowed es false, Retry-After (segundos enteros)" tested: true tests: ["setea X-RateLimit-Limit con el burst", "setea X-RateLimit-Remaining con result.Remaining", "setea X-RateLimit-Reset como timestamp unix", "incluye Retry-After cuando no esta permitido", "no incluye Retry-After cuando esta permitido"] test_file_path: "functions/infra/rate_limit_headers_test.go" file_path: "functions/infra/rate_limit_headers.go" --- ## Ejemplo ```go result := RateLimiterCheck(rl, "192.168.1.1") headers := RateLimitHeaders(result, 20) for k, v := range headers { w.Header()[k] = v } ``` ## Notas Funcion pura — sin I/O, sin estado, deterministica para una misma entrada. Sigue `draft-ietf-httpapi-ratelimit-headers`. `Retry-After` se redondea hacia arriba en segundos enteros (RFC 7231) y nunca se setea por debajo de 1 (sino el cliente reintenta inmediatamente). El timestamp en `X-RateLimit-Reset` es Unix epoch en segundos.