Browse Source

Fix norma etag field and media private path

- _norma_last_modified: use ultima_edicao instead of data_ultima_atualizacao
- serve_media: gate on sapl/private/ instead of documentos_privados/
- plan: update norma freshness field reference

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
rate-limiter-2026
Edward Ribeiro 2 weeks ago
parent
commit
f838a71d05
  1. 2
      plan/RATE-LIMITER-PLAN.md
  2. 4
      sapl/base/media.py
  3. 2
      sapl/norma/views.py

2
plan/RATE-LIMITER-PLAN.md

@ -1008,7 +1008,7 @@ class DetailView(AnonCachePageMixin, Crud.DetailView):
``` ```
`NormaCrud.DetailView` follows the same pattern with `_norma_last_modified` / `NormaCrud.DetailView` follows the same pattern with `_norma_last_modified` /
`_norma_etag` querying `NormaJuridica.data_ultima_atualizacao`. `_norma_etag` querying `NormaJuridica.ultima_edicao`.
**On a cache hit**: one `VALUES` query fires, Django returns `304` — view body, **On a cache hit**: one `VALUES` query fires, Django returns `304` — view body,
template render, and ORM work are all skipped. template render, and ORM work are all skipped.

4
sapl/base/media.py

@ -3,7 +3,7 @@ serve_media — X-Accel-Redirect gate for all /media/ files.
Production flow (nginx proxies /media/ to Gunicorn): Production flow (nginx proxies /media/ to Gunicorn):
1. Django middleware runs (IP rate-limit, bot UA check, etc.). 1. Django middleware runs (IP rate-limit, bot UA check, etc.).
2. serve_media() runs auth check for documentos_privados/, writes 2. serve_media() runs auth check for sapl/private/, writes
URL-path counter to Redis DB 1, then returns X-Accel-Redirect. URL-path counter to Redis DB 1, then returns X-Accel-Redirect.
Nginx serves the bytes directly from disk Gunicorn worker freed immediately. Nginx serves the bytes directly from disk Gunicorn worker freed immediately.
@ -51,7 +51,7 @@ def serve_media(request, path):
abs_path = _safe_resolve(path) abs_path = _safe_resolve(path)
# Auth gate for private documents — redirect to login if anonymous. # Auth gate for private documents — redirect to login if anonymous.
if path.startswith('documentos_privados/'): if path.startswith('sapl/private/'):
user = getattr(request, 'user', None) user = getattr(request, 'user', None)
if user is None or not user.is_authenticated: if user is None or not user.is_authenticated:
from django.contrib.auth.views import redirect_to_login from django.contrib.auth.views import redirect_to_login

2
sapl/norma/views.py

@ -281,7 +281,7 @@ class NormaTaView(IntegracaoTaView):
def _norma_last_modified(request, *args, **kwargs): def _norma_last_modified(request, *args, **kwargs):
return NormaJuridica.objects.filter( return NormaJuridica.objects.filter(
pk=kwargs['pk'] pk=kwargs['pk']
).values_list('data_ultima_atualizacao', flat=True).first() ).values_list('ultima_edicao', flat=True).first()
def _norma_etag(request, *args, **kwargs): def _norma_etag(request, *args, **kwargs):

Loading…
Cancel
Save