Metadata-Version: 2.4
Name: rex-tls
Version: 0.1.0
Classifier: Development Status :: 3 - Alpha
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Rust
Classifier: Topic :: Internet :: WWW/HTTP
Requires-Dist: certifi>=2024
Requires-Dist: maturin>=1.9,<2 ; extra == 'dev'
Requires-Dist: pytest>=8,<10 ; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.24,<2 ; extra == 'dev'
Requires-Dist: trustme>=1.2.1,<2 ; extra == 'dev'
Requires-Dist: websocket-client>=1.8,<2 ; extra == 'dev'
Requires-Dist: h2>=4.3,<4.4 ; python_full_version < '3.10' and extra == 'dev'
Requires-Dist: h2>=4.4,<5 ; python_full_version >= '3.10' and extra == 'dev'
Provides-Extra: dev
License-File: LICENSE
Summary: Python HTTP client with native Android Chrome and OkHttp TLS/HTTP2 profiles
Keywords: tls,http2,android,chrome,okhttp,boringssl
Author: rex-tls contributors
License: MIT
Requires-Python: >=3.9
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM

# rex-tls

`rex-tls` 是一个面向 Python 的原生 HTTP 客户端，专注于两个移动端配置族：

- Android Chrome：Chromium/BoringSSL TLS、ALPN、HTTP/1.1、HTTP/2 与 Android 请求头组合。
- OkHttp：各版本独立的 cipher、curve、signature algorithms 与 HTTP/2 SETTINGS 组合。

原生传输层由 Rust 扩展承载，Python API 负责参数编码、响应解码以及同步/异步易用接口。项目不包含验证码求解、WAF 绕过、反检测令牌或站点专用规避逻辑。

## 快速开始

```powershell
python -m pip install rex-tls
```

首选导入名是 `rex_tls`；现有 `mobile_tls` 导入继续作为兼容入口提供。

开发环境构建：

```powershell
py -3.11 -m pip install maturin pytest pytest-asyncio
py -3.11 -m maturin develop --release
py -3.11 -m pytest -m "not network"
```

Android Chrome：

```python
from rex_tls import Session

with Session("chrome_android_149") as session:
    response = session.get("https://example.com", params={"page": 1})
    print(response.status_code, response.http_version)
    print(response.text)
```

OkHttp：

```python
from rex_tls import Session

with Session("okhttp_4.12") as session:
    response = session.post(
        "https://example.com/api",
        json={"hello": "android"},
    )
    print(response.json())
```

异步接口：

```python
import asyncio
from rex_tls import AsyncSession

async def main() -> None:
    async with AsyncSession("chrome_android") as session:
        response = await session.get("https://example.com")
        print(response.status_code)

asyncio.run(main())
```

使用 `rex_tls.profiles()` 查看编译进扩展的全部配置。`chrome_android` 当前是 `chrome_android_150` 的别名，`okhttp` 当前是 `okhttp_4.12` 的别名；生产代码建议固定具体版本。

代理接口采用 requests 风格的 `proxies` 映射，也保留单代理快捷参数：

```python
import rex_tls

proxies = {
    "http": "http://user:password@proxy.example:8080",
    "https": "http://user:password@proxy.example:8080",
}

response = rex_tls.get(
    "https://example.com",
    profile="chrome_android_149",
    proxies=proxies,
    timeout=30,
)

with rex_tls.Session("okhttp_4.12") as session:
    session.proxies.update(proxies)
    session.headers.update({"x-client": "mobile"})
    response = session.get("https://example.com")
```

当前代理边界是 HTTP forward 与通过 HTTP 代理建立的 HTTPS CONNECT 隧道；支持
代理 URL 中的 Basic 认证、`Session.proxies`、单请求 `proxies=`、`trust_env` 和
`NO_PROXY`。不支持 HTTPS-proxy、SOCKS、PAC、NTLM/Digest 或 MASQUE。传统 CONNECT
不能承载 QUIC：选中代理时 `http3="auto"` 使用同一代理上的 H2/H1，`http3="only"`
在建立网络连接前明确拒绝。代理失败不会回退直连，`Proxy-Authorization` 也不会作为
普通源站请求头发送。

当前三个首发目标的工程状态：

> 公开 `Session` 使用基于 vendored BoringSSL 的项目自维护 TLS/HTTP 核心，release
> 依赖树中不包含 `wreq/wreq-util`。Chrome Android 149/150 的 QUIC/H3 网络路径、三次
> 独立 full-wire 真机差分、六场景恢复/0-RTT/回退矩阵和完整 L4 行为矩阵均已闭环；
> OkHttp 4.12 的完整 L4 矩阵也已闭环。三套配置均绑定到同一最终 Windows wheel/DLL
> 与本机门禁 run。迁移设计见
> [`docs/08-manual-core-architecture.md`](docs/08-manual-core-architecture.md)。

| profile | 实测平台 | 状态 |
|---|---|---|
| `chrome_android_149` | Pixel 4 / Android 11 / Chrome 149.0.7827.200 | TLS/H1/H2/H3 full-wire、恢复、0-RTT、回退与 21 类 L4 行为均为 `L4-behavior-equivalent` |
| `chrome_android_150` | Pixel 4 / Android 11 / Chrome 150.0.7871.63 | TLS/H1/H2/H3 full-wire、恢复、0-RTT、回退与 21 类 L4 行为均为 `L4-behavior-equivalent` |
| `okhttp_4.12` | Pixel 4 / Android 11 / AndroidOpenSSL / OkHttp 4.12.0 | 冷/恢复握手、H1/H2 与 18 类 L4 行为为 `L4-behavior-equivalent`；按能力边界不声明 H3 |

`okhttp_4.12` 当前明确代表上述 Android 11/provider 基线，不宣称覆盖所有 Android 版本。Android/provider 变化会建立新的具名 profile。

Windows 本机发布门禁已覆盖 Rust 全套测试、CPython 3.9/3.11/3.14 隔离安装、
H3 六场景、sdist 回编译安装、公开网络回归和真实设备证据检查。冻结候选的运行编号、
文件哈希和逐项结果记录在本地 gate summary 与 `captures/release-*` 证据目录中，并由
`tools/release_evidence.json` 的哈希清单约束；不在说明文件中硬编码易过期的候选编号。
四目标远程 CI 和发布流程仍是后续独立门禁，当前尚未上传 GitHub 或 PyPI。

## 指纹准确性的边界

同版本 Android 与桌面 Chrome 共用 Chromium 网络栈和 BoringSSL，协议指纹可能相同或高度相似。完整网络行为仍可能受到 Chromium 灰度实验、编译参数、CPU 能力、会话恢复和服务器协商结果影响。因此：

- 本项目不会声称 User-Agent 变化等于 TLS 指纹变化。
- 三个首发配置的设备 baseline 当前均为 `L4-behavior-equivalent`。
- 真实 Android 设备抓包回归通过后，才应将具体版本标记为 device-verified。
- JA3/JA4 只是完整握手的摘要，验收时应同时比较 ClientHello、ALPN/ALPS 和 HTTP/2 帧参数。

运行公网指纹回显测试：

```powershell
py -3.11 -m pytest -m network -q
```

采集多个独立冷连接并生成脱敏后的字段级观测：

```powershell
rex-tls-audit capture chrome_android_149 --runs 5 -o observation.json
```

比较两份规范化结果：

```powershell
rex-tls-audit diff expected.json actual.json
```

规范化过程不会保存源 IP、SNI 值、Cookie、Authorization、Client Random、session id 或临时密钥内容。临时密钥只保留算法位置与字节长度。

Chrome 149 的 exact-tag 源码审计、稳定默认值、真机必测项以及当前 BoringSSL
revision 差距见 [`docs/06-chrome149-source-audit.md`](docs/06-chrome149-source-audit.md)。
三次 Chrome 149 真实 cold 样本落盘后的只读验收命令见
[`docs/07-chrome149-capture-acceptance.md`](docs/07-chrome149-capture-acceptance.md)。

## 安全默认值

- 默认验证服务器证书和主机名。
- 默认不读取系统代理环境变量；设置 `trust_env=True` 后才读取 HTTP(S)_PROXY 和
  NO_PROXY。代理失败不会静默直连。
- `verify=False` 只应在受控测试环境中使用。
- 项目定位为协议兼容、客户端测试和经授权的研究工具。

## 发布 wheel

```powershell
py -3.11 -m maturin build --release --out dist
```

PyO3 使用 `abi3-py39`，同一平台 wheel 可兼容 CPython 3.9 及以上版本。BoringSSL 会静态进入原生扩展，最终 wheel 不依赖用户预装 OpenSSL。

当前仅完成 Windows 本机构建与 CPython 3.9/3.11 运行验证；其他操作系统/架构仍须由多平台 CI
构建和测试后才能进入发布门禁。上面的命令只生成本地产物，不会自动上传 PyPI。

## 原生依赖

- vendored `btls-sys` / BoringSSL：TLS 密码学与握手后端；
- 项目自维护 Rust 模块：HTTP/1.1、HTTP/2、HPACK 与会话策略；QUIC Initial、HTTP/3、QPACK
  以及为显式 Chrome Android 149/150 profile 提供的 QUIC/H3 网络栈；OkHttp 不声明 H3，
  Chrome H3 的完整真机 wire-shape、恢复/0-RTT/回退和 L4 行为门禁均已闭环；
- `brotli`、`flate2`、`zstd`：有界响应内容解码；
- `PyO3`：Python 原生扩展绑定（MIT OR Apache-2.0）。

## 2026-08-12 本机发布候选状态

本节取代上文的旧测试数量。公开开发接口现已为 Chrome Android 149 和 150 提供显式启用的
HTTP/3 路径：

```python
from rex_tls import Session

with Session("chrome_android_149", http3="only") as session:
    response = session.get("https://example.com")
```

将 profile 改为显式的 `chrome_android_150` 使用同一路径。该路径不会静默回退。OkHttp H3、
代理模式和非 HTTPS URL 会被拒绝；OkHttp 4.12 正确保持 HTTP/2 + HTTP/1.1。公开 capability 为
`http3_network=chrome_android_149,chrome_android_150`。

三个首发 profile 的真机证据现均达到 `L4-behavior-equivalent`。Windows 本机门禁覆盖同一 ABI3
wheel 在 CPython 3.9/3.11/3.14 的隔离安装、从 sdist 重新编译安装、H1/H2/H3、本地会话矩阵、
公网指纹回显、依赖/隐私审计及连接真机证据重放。冻结候选的运行编号、产物哈希和逐项结果只记录在
版本化证据清单及发布检查点中，避免 README 固化易过期的构建值。

本机通过只允许进入下一阶段，不等于已经发布。Windows、manylinux x86-64、macOS x86-64、
macOS arm64 四目标 GitHub CI、TestPyPI 安装回归和 PyPI Trusted Publishing 仍是独立门禁；
这些远程步骤完成前不会声明正式 `release_ready=true`。

