docs: Task5 收口注记与 Task6/7 指令更新(geo 单例/0占位归一/::ffff: 归一/IPv6 接受)
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -669,6 +669,7 @@ class GeoResolver:
|
||||
return None
|
||||
```
|
||||
注:py-ip2region 的实际调用以其 README 为准(模块 `ip2region`,入口 `searcher.new_with_buffer(buff)` 后 `search(ip)`;**不支持 with 上下文管理器**——用错会被 except 静默吞掉、地理功能永久失效且测试照样绿,务必按此实现)。解析结果格式 `国家|区域|省|市|ISP`,如 `中国|0|广东省|深圳市|电信`、`美国|0|加利福尼亚|旧金山|0`。
|
||||
(**执行注记**:实际交付以提交为准——py-ip2region 3.0.4 `new_with_buffer(version, c_buffer)` 双参、现行 GitHub 库已改名 ip2region_v4.xdb 且五段布局为 `国家|省|城市|ISP|国家代码`(旧映射会把 ISP 串进 city),实现按 xdb 头版本分派新旧布局;xdb 外国条目为英文;"0" 为缺失占位(Task 6 写库时归一为空串);模块级导出 `resolver` 单例;**IPv6 M1 显示"未知"(v4-only 库,已接受)**;Task 7 的 `_client_ip` 需归一 `::ffff:` 前缀的 IPv4 映射地址防地理丢失。)
|
||||
|
||||
- [ ] **Step 3: 跑测试通过**(`server/.gitignore` 加 `tracker/data/*.xdb`)
|
||||
|
||||
@@ -749,9 +750,8 @@ from django.utils import timezone
|
||||
from tracker import constants as C
|
||||
from tracker.models import Visitor, VisitSession, Event
|
||||
from tracker.services.validation import validate_event
|
||||
from tracker.services.geo import GeoResolver
|
||||
|
||||
_geo = GeoResolver()
|
||||
from tracker.services.geo import resolver as _geo # 模块级单例(勿再实例化,11MB/份)
|
||||
# geo 返回值缺失段为 "0" 占位:写库前归一 x if x not in ("", "0") else ""
|
||||
|
||||
_FIELD_LEN = {"device_type": 16, "os": 64, "browser": 64, "language": 32, "screen": 32}
|
||||
|
||||
@@ -1034,9 +1034,11 @@ class CollectBatchView(APIView):
|
||||
def _client_ip(self, request):
|
||||
"""nginx 前置时取 X-Forwarded-For 最后一段(与 DRF NUM_PROXIES=1 一致;套 CDN 时按层数前移)。"""
|
||||
xff = request.META.get("HTTP_X_FORWARDED_FOR", "")
|
||||
if xff:
|
||||
return xff.split(",")[-1].strip()
|
||||
return request.META.get("REMOTE_ADDR")
|
||||
ip = xff.split(",")[-1].strip() if xff else request.META.get("REMOTE_ADDR")
|
||||
# 归一 IPv4 映射地址(::ffff:1.2.3.4 → 1.2.3.4),防地理解析丢失
|
||||
if ip and ip.lower().startswith("::ffff:"):
|
||||
ip = ip[7:]
|
||||
return ip
|
||||
|
||||
def _deny(self, code, reason):
|
||||
resp = Response({"code": code, "data": None, "message": reason}, status=code)
|
||||
|
||||
Reference in New Issue
Block a user