fix(server): v2入口加固——page_id孤代理/NaN区间值拒绝,共享ISO解析

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-09-18 11:53:02 +08:00
parent 8459e6fa13
commit 5e024b814b
4 changed files with 73 additions and 33 deletions
+2 -10
View File
@@ -1,5 +1,4 @@
import json
from datetime import datetime, timezone as dt_tz
from urllib.parse import urlsplit
from uuid import uuid4
from django.utils import timezone as dj_timezone
@@ -11,7 +10,7 @@ from rest_framework.parsers import BaseParser
from rest_framework.settings import api_settings
from tracker.models import RawBatch, Site, Visitor
from tracker.services.ingest import ingest_batch
from tracker.services.validation import sanitize_payload
from tracker.services.validation import parse_iso_dt, sanitize_payload
class PlainJSONParser(BaseParser):
media_type = "text/plain"
@@ -30,13 +29,6 @@ class CollectThrottle(AnonRateThrottle):
# override_settings 改 DEFAULT_THROTTLE_RATES 对它不生效——改读实时 api_settings(DRF 收 setting_changed 会 reload)
return api_settings.DEFAULT_THROTTLE_RATES[self.scope]
def _iso(dt):
if isinstance(dt, str):
s = dt.replace("Z", "+00:00")
d = datetime.fromisoformat(s)
return d if d.tzinfo else d.replace(tzinfo=dt_tz.utc) # Django≥5 已删除 django.utils.timezone.utc
return dt
class CollectBatchView(APIView):
permission_classes = [AllowAny]
parser_classes = [PlainJSONParser]
@@ -66,7 +58,7 @@ class CollectBatchView(APIView):
for ev in payload.get("events") or []:
if isinstance(ev, dict) and "occurred_at" in ev:
try:
ev["occurred_at"] = _iso(ev["occurred_at"])
ev["occurred_at"] = parse_iso_dt(ev["occurred_at"]) # 共享解析(validation),视图错误策略=整批 400
except (ValueError, TypeError):
return self._deny(400, "invalid_occurred_at", request_id)
if not payload.get("visitor_id") or not payload.get("session_id"):