starainrt 732e81316c
fix(starnet): 重构请求执行链路并补齐代理/重试/trace边界
- 分离 Request 的配置态与执行态,修复二次 Do、raw 模式网络配置失效和 body 来源互斥问题
  - 新增 starnet trace 抽象,补齐 DNS/连接/TLS/重试事件,并优化动态 transport 缓存与代理解析路径
  - 收紧非法代理为 fail-fast,多目标目标回退仅限幂等请求,修复 Host/TLS/SNI 等语义边界
  - 补充防御性拷贝、专项回归测试、本地代理/TLS 用例与 README 行为说明
2026-04-19 15:39:51 +08:00
2026-03-08 20:19:40 +08:00
2026-03-08 20:19:40 +08:00
2026-03-08 20:19:40 +08:00
2026-03-08 20:19:40 +08:00
2026-03-08 20:19:40 +08:00
2026-03-08 20:19:40 +08:00
2026-03-19 16:42:45 +08:00
2026-03-19 16:42:45 +08:00
2026-03-19 16:42:45 +08:00
2026-03-08 20:19:40 +08:00
2024-08-08 22:03:10 +08:00
2024-08-08 22:03:10 +08:00
2026-03-08 20:19:40 +08:00
2026-03-08 20:19:40 +08:00
2026-03-19 16:42:45 +08:00
2026-03-08 20:19:40 +08:00
2026-03-19 16:42:45 +08:00
2026-03-08 20:19:40 +08:00
2026-03-08 20:19:40 +08:00
2026-03-08 20:19:40 +08:00
2026-03-19 16:42:45 +08:00
2026-03-08 20:19:40 +08:00
2026-03-19 16:42:45 +08:00
2026-03-19 16:42:45 +08:00
2026-03-19 16:42:45 +08:00
2026-03-08 20:19:40 +08:00
2026-03-08 20:19:40 +08:00

starnet

starnet 是一个面向 Go 的网络工具库,提供 HTTP 请求控制、TLS 嗅探和 ICMP Ping 能力。

功能概览

  • 基于 context 的请求级超时控制,不修改共享 http.Client 的全局超时
  • 请求级网络控制:代理、自定义 IP / DNS、拨号超时、TLS 配置
  • 内置重试机制,支持重试次数、退避、抖动、状态码白名单和自定义错误判定
  • 响应体大小限制,避免一次性读取过大内容
  • 错误分类辅助:ClassifyErrorIsTimeoutIsDNSIsTLSIsProxyIsCanceled
  • TLS 嗅探监听 / 拨号工具,适用于 TLS 与明文混合场景
  • ICMP Ping支持 IPv4 / IPv6 目标和选项化探测

主要能力

HTTP 客户端与请求构建

  • 同时提供 WithXxx 选项和 SetXxx 链式调用两套接口
  • 支持 GetPostPutDeleteHeadPatchOptionsTraceConnect
  • 支持 JSON、表单、multipart/form-data、流式请求体等常见请求体形态
  • Header、Cookie、Query 等输入在关键路径上做防御性拷贝,降低外部可变状态污染风险
  • Request.Clone() 可用于并发场景或同一基础请求的变体构造

超时与重试

  • 请求超时通过 context 截止时间控制,不污染共享客户端配置
  • 重试支持:
    • 最大尝试次数
    • 基础退避、最大退避和退避因子
    • 抖动比例
    • 可重试状态码集合
    • 仅幂等方法重试
    • 自定义错误判定函数
  • 重试成功后返回的 Response 仍保持对原始 Request 的引用

响应处理

  • 提供 BytesStringJSONReader 等响应体读取接口
  • 支持自动预取响应体
  • 支持按字节数限制响应体读取上限

Ping 模块

  • 提供 PingPingWithContextPingable 以及兼容函数 IsIpPingable
  • PingOptions 支持次数、超时、间隔、截止时间、地址族偏好、源地址、负载长度等参数
  • 对权限不足、协议不支持、超时、解析失败等情况提供明确错误语义

安装

go get b612.me/starnet

快速示例

package main

import (
    "fmt"
    "net/http"
    "time"

    "b612.me/starnet"
)

func main() {
    resp, err := starnet.Get(
        "https://example.com",
        starnet.WithTimeout(2*time.Second),
        starnet.WithRetry(2,
            starnet.WithRetryBackoff(100*time.Millisecond, 1*time.Second, 2),
            starnet.WithRetryJitter(0.1),
        ),
        starnet.WithMaxRespBodyBytes(1<<20),
    )
    if err != nil {
        fmt.Println("request failed:", starnet.ClassifyError(err), err)
        return
    }
    defer resp.Close()

    fmt.Println("status:", resp.StatusCode)
    _, _ = resp.Body().Bytes()

    ok, pingErr := starnet.Pingable("example.com", &starnet.PingOptions{
        Count:   2,
        Timeout: 2 * time.Second,
    })
    fmt.Println("pingable:", ok, pingErr == nil)

    _ = http.MethodGet
}

行为说明

  • NewClientNewRequest 以及请求构造相关接口在遇到非法选项时会直接返回错误,例如格式不合法的代理地址。
  • NewClientNoErr 是便利构造函数;如果选项校验失败,仍可能返回一个占位 Client,需要严格校验配置时应优先使用 NewClient
  • 重试默认仅对幂等方法生效。即使显式关闭“仅幂等方法重试”,通过 SetBodyReaderWithBodyReader 构造的请求在非幂等方法上仍不会自动重试。
  • 当同时使用 proxy + custom IP/DNS 且解析出多个目标地址时,自动目标回退仅对幂等请求生效,以避免重复写入。

稳定性说明

  • 原始 ICMP Ping 在部分系统上需要额外权限。
  • 依赖外部网络环境的集成测试结果可能受运行环境影响。

许可证

本项目采用 Apache License 2.0,详见 LICENSE

Description
No description provided
Readme Apache-2.0 516 KiB
v0.4.4 Latest
2026-03-27 12:29:28 +08:00
Languages
Go 100%