mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 17:30:23 +08:00
refactor(fingerprint): 移除请求头构建路径中的 per-key 指纹定制化注入
headers.py 删除 build_browser_fingerprint_headers / build_anthropic_extra_headers 函数及相关辅助,改为直接使用固定常量;PassthroughRequestBuilder 移除 Claude 格式的指纹注入步骤;Antigravity constants 移除 per-key 指纹 覆盖逻辑,统一使用进程级固定值。
This commit is contained in:
@@ -22,8 +22,6 @@ from typing import Any
|
|||||||
from src.core.api_format import (
|
from src.core.api_format import (
|
||||||
UPSTREAM_DROP_HEADERS,
|
UPSTREAM_DROP_HEADERS,
|
||||||
HeaderBuilder,
|
HeaderBuilder,
|
||||||
build_anthropic_extra_headers,
|
|
||||||
build_browser_fingerprint_headers,
|
|
||||||
get_auth_config_for_endpoint,
|
get_auth_config_for_endpoint,
|
||||||
make_signature_key,
|
make_signature_key,
|
||||||
)
|
)
|
||||||
@@ -31,7 +29,6 @@ from src.core.crypto import crypto_service
|
|||||||
from src.models.endpoint_models import _CONDITION_OPS, _TYPE_IS_VALUES, parse_re_flags
|
from src.models.endpoint_models import _CONDITION_OPS, _TYPE_IS_VALUES, parse_re_flags
|
||||||
from src.services.provider.auth import get_provider_auth # noqa: F401
|
from src.services.provider.auth import get_provider_auth # noqa: F401
|
||||||
from src.services.provider.envelope import ProviderEnvelope
|
from src.services.provider.envelope import ProviderEnvelope
|
||||||
from src.services.provider.request_context import get_current_fingerprint
|
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# 统一的头部配置常量
|
# 统一的头部配置常量
|
||||||
@@ -1243,13 +1240,7 @@ class PassthroughRequestBuilder(RequestBuilder):
|
|||||||
if header_rules:
|
if header_rules:
|
||||||
builder.apply_rules(header_rules, protected_keys)
|
builder.apply_rules(header_rules, protected_keys)
|
||||||
|
|
||||||
# 4. 注入 per-key 指纹头(仅 Claude 格式需要浏览器指纹绕过 Cloudflare 检测)。
|
# 4. 添加额外头部
|
||||||
if str(endpoint_sig or "").strip().lower().startswith("claude:"):
|
|
||||||
fp = get_current_fingerprint()
|
|
||||||
builder.add_many(build_browser_fingerprint_headers(fp))
|
|
||||||
builder.add_many(build_anthropic_extra_headers(fp))
|
|
||||||
|
|
||||||
# 5. 添加额外头部
|
|
||||||
effective_extra_headers = self._merge_extra_headers_with_original(
|
effective_extra_headers = self._merge_extra_headers_with_original(
|
||||||
original_headers,
|
original_headers,
|
||||||
extra_headers,
|
extra_headers,
|
||||||
@@ -1258,10 +1249,10 @@ class PassthroughRequestBuilder(RequestBuilder):
|
|||||||
if effective_extra_headers:
|
if effective_extra_headers:
|
||||||
builder.add_many(effective_extra_headers)
|
builder.add_many(effective_extra_headers)
|
||||||
|
|
||||||
# 6. 设置认证头(最高优先级,上游始终使用 header 认证)
|
# 5. 设置认证头(最高优先级,上游始终使用 header 认证)
|
||||||
builder.add(auth_header, auth_value)
|
builder.add(auth_header, auth_value)
|
||||||
|
|
||||||
# 7. 确保有 Content-Type
|
# 6. 确保有 Content-Type
|
||||||
headers = builder.build()
|
headers = builder.build()
|
||||||
if not any(k.lower() == "content-type" for k in headers):
|
if not any(k.lower() == "content-type" for k in headers):
|
||||||
headers["Content-Type"] = "application/json"
|
headers["Content-Type"] = "application/json"
|
||||||
|
|||||||
@@ -32,8 +32,6 @@ from src.core.api_format.headers import (
|
|||||||
HeaderBuilder,
|
HeaderBuilder,
|
||||||
build_adapter_base_headers_for_endpoint,
|
build_adapter_base_headers_for_endpoint,
|
||||||
build_adapter_headers_for_endpoint,
|
build_adapter_headers_for_endpoint,
|
||||||
build_anthropic_extra_headers,
|
|
||||||
build_browser_fingerprint_headers,
|
|
||||||
build_upstream_headers_for_endpoint,
|
build_upstream_headers_for_endpoint,
|
||||||
detect_capabilities_for_endpoint,
|
detect_capabilities_for_endpoint,
|
||||||
extract_client_api_key_for_endpoint,
|
extract_client_api_key_for_endpoint,
|
||||||
@@ -121,8 +119,6 @@ __all__ = [
|
|||||||
"detect_capabilities_for_endpoint",
|
"detect_capabilities_for_endpoint",
|
||||||
"HeaderBuilder",
|
"HeaderBuilder",
|
||||||
"build_upstream_headers_for_endpoint",
|
"build_upstream_headers_for_endpoint",
|
||||||
"build_browser_fingerprint_headers",
|
|
||||||
"build_anthropic_extra_headers",
|
|
||||||
"merge_headers_with_protection",
|
"merge_headers_with_protection",
|
||||||
"filter_response_headers",
|
"filter_response_headers",
|
||||||
"redact_headers_for_log",
|
"redact_headers_for_log",
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
from collections.abc import Set as AbstractSet
|
from collections.abc import Set as AbstractSet
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import Any
|
||||||
|
|
||||||
from src.core.api_format.enums import ApiFamily
|
from src.core.api_format.enums import ApiFamily
|
||||||
from src.core.api_format.metadata import (
|
from src.core.api_format.metadata import (
|
||||||
@@ -26,9 +26,6 @@ from src.core.api_format.metadata import (
|
|||||||
from src.core.api_format.signature import EndpointSignature, parse_signature_key
|
from src.core.api_format.signature import EndpointSignature, parse_signature_key
|
||||||
from src.core.logger import logger
|
from src.core.logger import logger
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from src.services.provider.fingerprint import FingerprintProfile
|
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# 头部常量定义
|
# 头部常量定义
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@@ -128,59 +125,6 @@ RESPONSE_DROP_HEADERS: frozenset[str] = (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
_DEFAULT_CHROME_MAJOR = "140"
|
|
||||||
|
|
||||||
|
|
||||||
def _extract_chrome_major(version: str) -> str:
|
|
||||||
value = str(version or "").strip()
|
|
||||||
if not value:
|
|
||||||
return _DEFAULT_CHROME_MAJOR
|
|
||||||
return value.split(".", 1)[0] or _DEFAULT_CHROME_MAJOR
|
|
||||||
|
|
||||||
|
|
||||||
def _resolve_sec_ch_platform(fp: FingerprintProfile) -> str:
|
|
||||||
os_name = (fp.stainless_os or "").strip().lower()
|
|
||||||
platform_info = (fp.platform_info or "").strip().lower()
|
|
||||||
|
|
||||||
if os_name.startswith("win") or "windows" in platform_info:
|
|
||||||
return '"Windows"'
|
|
||||||
if os_name in {"mac", "macos", "darwin"} or "darwin" in platform_info:
|
|
||||||
return '"macOS"'
|
|
||||||
return '"Linux"'
|
|
||||||
|
|
||||||
|
|
||||||
def build_browser_fingerprint_headers(fp: FingerprintProfile | None = None) -> dict[str, str]:
|
|
||||||
"""Build browser fingerprint headers, optionally overridden by per-key fingerprint."""
|
|
||||||
headers = {**BROWSER_FINGERPRINT_HEADERS}
|
|
||||||
if fp is None:
|
|
||||||
return headers
|
|
||||||
|
|
||||||
chrome_major = _extract_chrome_major(fp.chrome_version)
|
|
||||||
headers["User-Agent"] = fp.user_agent or headers["User-Agent"]
|
|
||||||
headers["sec-ch-ua"] = f'"Not=A?Brand";v="24", "Chromium";v="{chrome_major}"'
|
|
||||||
headers["sec-ch-ua-platform"] = _resolve_sec_ch_platform(fp)
|
|
||||||
return headers
|
|
||||||
|
|
||||||
|
|
||||||
def build_anthropic_extra_headers(fp: FingerprintProfile | None = None) -> dict[str, str]:
|
|
||||||
"""Build Anthropic extra headers, optionally overridden by per-key fingerprint."""
|
|
||||||
headers = {**_ANTHROPIC_EXTRA_HEADERS}
|
|
||||||
if fp is None:
|
|
||||||
return headers
|
|
||||||
|
|
||||||
headers["x-stainless-os"] = fp.stainless_os or headers["x-stainless-os"]
|
|
||||||
headers["x-stainless-arch"] = fp.stainless_arch or headers["x-stainless-arch"]
|
|
||||||
headers["x-stainless-package-version"] = (
|
|
||||||
fp.stainless_package_version or headers["x-stainless-package-version"]
|
|
||||||
)
|
|
||||||
# browser:chrome runtime-version = Chrome 版本;
|
|
||||||
# CLI 路径(ClaudeCodeEnvelope)使用 Node.js,其 extra_headers 会以 fp.stainless_runtime_version 覆盖。
|
|
||||||
headers["x-stainless-runtime-version"] = (
|
|
||||||
fp.chrome_version or headers["x-stainless-runtime-version"]
|
|
||||||
)
|
|
||||||
return headers
|
|
||||||
|
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# 请求头规范化
|
# 请求头规范化
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@@ -624,12 +568,12 @@ def build_adapter_base_headers_for_endpoint(
|
|||||||
auth_value = f"Bearer {api_key}" if auth_type == "bearer" else api_key
|
auth_value = f"Bearer {api_key}" if auth_type == "bearer" else api_key
|
||||||
|
|
||||||
# 以浏览器指纹为底层默认值,绕过 Cloudflare 等反爬防护
|
# 以浏览器指纹为底层默认值,绕过 Cloudflare 等反爬防护
|
||||||
headers: dict[str, str] = build_browser_fingerprint_headers()
|
headers: dict[str, str] = {**BROWSER_FINGERPRINT_HEADERS}
|
||||||
|
|
||||||
# Claude API family 额外注入 Anthropic 专属 header
|
# Claude API family 额外注入 Anthropic 专属 header
|
||||||
definition = resolve_endpoint_definition(endpoint)
|
definition = resolve_endpoint_definition(endpoint)
|
||||||
if definition and definition.api_family == ApiFamily.CLAUDE:
|
if definition and definition.api_family == ApiFamily.CLAUDE:
|
||||||
headers.update(build_anthropic_extra_headers())
|
headers.update(_ANTHROPIC_EXTRA_HEADERS)
|
||||||
|
|
||||||
headers[auth_header] = auth_value
|
headers[auth_header] = auth_value
|
||||||
headers["Content-Type"] = "application/json"
|
headers["Content-Type"] = "application/json"
|
||||||
|
|||||||
@@ -14,8 +14,6 @@ import uuid
|
|||||||
# ============== API 端点 ==============
|
# ============== API 端点 ==============
|
||||||
# 唯一定义在 core 层,此处 re-export 保持向后兼容
|
# 唯一定义在 core 层,此处 re-export 保持向后兼容
|
||||||
from src.core.provider_templates.fixed_providers import ANTIGRAVITY_PROD_URL as PROD_BASE_URL
|
from src.core.provider_templates.fixed_providers import ANTIGRAVITY_PROD_URL as PROD_BASE_URL
|
||||||
from src.services.provider.fingerprint import resolve_platform_token
|
|
||||||
from src.services.provider.request_context import get_current_fingerprint
|
|
||||||
|
|
||||||
DAILY_BASE_URL = "https://daily-cloudcode-pa.googleapis.com"
|
DAILY_BASE_URL = "https://daily-cloudcode-pa.googleapis.com"
|
||||||
SANDBOX_BASE_URL = "https://daily-cloudcode-pa.sandbox.googleapis.com"
|
SANDBOX_BASE_URL = "https://daily-cloudcode-pa.sandbox.googleapis.com"
|
||||||
@@ -114,43 +112,17 @@ URL_UNAVAILABLE_TTL_SECONDS = 300 # 5 分钟
|
|||||||
_SESSION_ID = uuid.uuid4().hex # 每次进程启动生成一个固定 session ID
|
_SESSION_ID = uuid.uuid4().hex # 每次进程启动生成一个固定 session ID
|
||||||
|
|
||||||
|
|
||||||
def _normalize_node_version(raw: str | None) -> str:
|
|
||||||
text = str(raw or "").strip()
|
|
||||||
if text.startswith(("v", "V")):
|
|
||||||
text = text[1:]
|
|
||||||
return text or "18.18.2"
|
|
||||||
|
|
||||||
|
|
||||||
def get_v1internal_extra_headers() -> dict[str, str]:
|
def get_v1internal_extra_headers() -> dict[str, str]:
|
||||||
"""构建 v1internal 请求需要的额外 header(对齐 AM upstream/client.rs)。"""
|
"""构建 v1internal 请求需要的额外 header(对齐 AM upstream/client.rs)。"""
|
||||||
fp = get_current_fingerprint()
|
|
||||||
with _ua_lock:
|
with _ua_lock:
|
||||||
version = _ua_version
|
version = _ua_version
|
||||||
|
|
||||||
user_agent = get_http_user_agent()
|
|
||||||
session_id = _SESSION_ID
|
|
||||||
node_version = "18.18.2"
|
|
||||||
|
|
||||||
if fp:
|
|
||||||
user_agent = _build_antigravity_http_user_agent(
|
|
||||||
platform_token=resolve_platform_token(
|
|
||||||
platform_info=fp.platform_info,
|
|
||||||
stainless_os=fp.stainless_os,
|
|
||||||
stainless_arch=fp.stainless_arch,
|
|
||||||
),
|
|
||||||
version=version,
|
|
||||||
chrome_version=fp.chrome_version or _FALLBACK_CHROME,
|
|
||||||
electron_version=fp.electron_version or _FALLBACK_ELECTRON,
|
|
||||||
)
|
|
||||||
session_id = fp.vscode_session_id or _SESSION_ID
|
|
||||||
node_version = _normalize_node_version(fp.node_version)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"User-Agent": user_agent,
|
"User-Agent": get_http_user_agent(),
|
||||||
"x-client-name": "antigravity",
|
"x-client-name": "antigravity",
|
||||||
"x-client-version": version,
|
"x-client-version": version,
|
||||||
"x-vscode-sessionid": session_id,
|
"x-vscode-sessionid": _SESSION_ID,
|
||||||
"x-goog-api-client": f"gl-node/{node_version} fire/0.8.6 grpc/1.10.x",
|
"x-goog-api-client": "gl-node/18.18.2 fire/0.8.6 grpc/1.10.x",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user