
OkCurl 实战指南基于 OkHttp 引擎的 curl 克隆命令行工具【免费下载链接】okhttpA meticulous HTTP client for the JVM, Android, and GraalVM.项目地址: https://gitcode.com/gh_mirrors/okh/okhttpOkCurl 是 OkHttp 官方仓库中附带的一个「下一代会话级 curl」——一个以 OkHttp 为底层 HTTP 引擎、用 Kotlin 与 Clikt 编写的 curl 克隆专门用于把 OkHttp 的完整 HTTP 引擎包括 HTTP/2、连接池、重定向、TLS直接暴露在命令行下进行验证。读完本文你将掌握 OkCurl 的构建运行方式、全部命令行参数语义、请求/响应构造的源码实现路径以及如何利用它对真实 Web 服务器做 HTTP/2 帧级与 TLS 级的调试。OkCurl 是什么定位与设计初衷根据 okcurl/README.md 的定位说明OkCurl 是A curl for the next-generation web即「面向下一代 Web 的 curl」。它的核心价值在于以 OkHttp 作为真正的网络引擎命令行发出的每个请求都会走 OkHttp 完整的调用链拦截器、连接池、协议协商、重定向等借助 OkHttp 对 HTTP/2 的原生支持可以直接在命令行验证服务器对 HTTP/2 的行为以 GraalVM 原生镜像方式打包具备接近原生 CLI 的启动速度适合作为日常开发调试工具。与系统自带的curl不同OkCurl 测试的不是 libcurl 的协议实现而是 OkHttp 的协议实现——这使它成为 OkHttp 开发者、贡献者以及想对比服务器对不同 HTTP 客户端行为差异的工程师的实用工具。构建与运行从源码到可执行文件仓库根目录下的 okcurl/okcurl 是一个 shell 启动脚本其内容如下#!/bin/sh -e ../gradlew -q --console plain nativeBuild ./build/graal/okcurl $也就是说运行 OkCurl 的完整流程是确保已经安装了 GraalVM并且环境变量GRAALVM_HOME已正确设置README 明确要求make sure you have GRAALVM_HOME set执行./okcurl脚本先调用 Gradle 的nativeBuild任务将 OkCurl 编译为 GraalVM 原生镜像镜像产物位于okcurl/build/graal/okcurl随后脚本直接执行它并把命令行参数原样透传。整个构建是静默的-q --console plain因此首次运行时只会在编译阶段等待片刻之后每次运行都几乎瞬时启动。版本信息来自模板文件 okcurl/src/main/resources-templates/okcurl-version.properties内容为version${projectVersion}构建时由 Gradle 注入项目版本号在开发环境中读取不到时会回退为dev见 Main.kt 的versionString()实现。命令行参数全解析对照 curl 语义OkCurl 的命令行解析由 Clikt 框架实现全部参数定义集中在 Main.kt 中。它与 curl 的常用参数保持了高度一致的命名习惯下表完整列出了所有可用选项、默认值及其底层行为参数短选项说明默认值/行为--request-X指定请求方法如PUT、DELETE不传时按是否有-d自动决定见下文--data-dHTTP POST 数据作为请求体发送无一旦提供请求方法默认变为POST--header-H自定义请求头可重复传入多次无--user-agent-A发送给服务器的 User-Agent默认okcurl/version--connect-timeout—连接建立的最大允许时间秒-1即不额外设置使用 OkHttp 默认--read-timeout—读取数据的最大允许时间秒-1同上--call-timeout—整个调用的最大允许时间秒-1同上--location-L跟随重定向关闭开启后同步配置 OkHttp 的 SSL 重定向跟随--insecure-k允许连接无证书/证书无效的 HTTPS 站点关闭--include-i在输出中包含协议响应头关闭--frames—将 HTTP/2 帧日志输出到 STDERR关闭--referer-e设置 Referer 头无--verbose-v输出详细的操作日志关闭--sslDebug—输出 SSL 调试日志关闭url位置参数—目标资源 URL必填缺失时报错其中三个超时参数的默认值-1是一个特殊哨兵值DEFAULT_TIMEOUT见 Main.kt只有当用户显式传入非-1的秒数时代码才会调用builder.connectTimeout(...)等方法覆盖 OkHttp 的默认超时配置从而保证不设置与设置为 0 秒两种语义被严格区分。基础使用示例# 最简单的 GET 请求 ./okcurl https://example.com # 发送 POST 表单数据 ./okcurl -d nameokhttplangkotlin https://example.com/api # 自定义方法 数据PUT ./okcurl -X PUT -d {key:value} \ -H Content-Type: application/json https://example.com/resource # 跟随重定向并显示响应头 ./okcurl -L -i https://example.com # 忽略证书校验访问自签名站点 ./okcurl -k https://self-signed.example.com # 查看 HTTP/2 帧级日志 ./okcurl --frames https://example.com # 自定义 User-Agent 与 Referer ./okcurl -A MyAgent/1.0 -e https://referer.example.com https://example.com帮助信息与空参数行为Main继承自 Clikt 的CliktCommand并设置了printHelpOnEmptyArgs true因此不带任何参数直接运行./okcurl会打印完整的使用帮助方便随时查阅所有选项。入口在 MainCommandLine.ktmain()调用Main().main(args)完成解析与执行随后调用exitProcess(0)确保原生镜像进程干净退出。请求构造的源码实现OkCurl 的请求构造逻辑集中在 internal/-MainCommon.kt 的commonCreateRequest()中其行为可以归纳为几条清晰的规则方法推导显式传入-X/--request时使用指定方法否则若提供了-d/--data则方法为POST否则为GET。URL 校验位置参数url缺失时直接抛出IOException(No url provided)避免构造出无效请求。请求体-d的内容通过toRequestBody(mediaType())转为RequestBodyContent-Type 的推导规则见下。请求头解析每个-H头按split(:, limit 2)切分为名称与值limit 2保证值中即使包含冒号也不会被误切例如If-Modified-Since: Mon, 18 Aug 2014 15:16:06 GMT这类带冒号的日期值其中Content-Type被视为特殊头不会重复写入请求头而是被提取出来作为请求体的媒体类型。默认媒体类型若-H中未提供Content-Type请求体默认使用application/x-www-form-urlencoded见 mediaType()。固定头Referer若提供与User-Agent恒为okcurl/version除非-A覆盖总会写入请求。测试对请求构造行为的印证MainTest.kt 用一组简洁的断言锁定了上述语义simple()无参数时方法为GET、无请求体put()/dataPut()-X PUT -d foo得到方法PUT、body 长度 3dataPost()仅-d foo时方法自动为POSTContent-Type 为application/x-www-form-urlencoded; charsetutf-8contentTypeHeader()通过-H Content-Type: application/json可覆盖请求体类型为application/json; charsetutf-8referer()/userAgent()/defaultUserAgent()分别验证-e、-A的生效以及默认 User-Agent 以okcurl/开头headerSplitWithDate()验证带冒号与逗号的日期头值能被完整保留。这些测试表明OkCurl 的请求层行为是经过严格回归保障的你可以在命令行中放心依赖上述语义。客户端配置与 TLS 处理createClient()Main.kt负责把命令行选项映射为OkHttpClient的配置重定向builder.followSslRedirects(followRedirects)将-L的语义同步到 SSL 重定向跟随配置上与 curl 的-L行为对齐超时仅在选项非-1时覆盖connectTimeout/readTimeout/callTimeout单位换算为SECONDS不安全模式-k开启时代码构造了一个信任一切的X509TrustManagercheckClientTrusted/checkServerTrusted均空实现并通过Platform.get().newSSLContext()生成对应的SSLSocketFactory同时把HostnameVerifier替换为恒返回true的实现——这是对 curl-k语义的完整复刻仅建议用于自签名证书或本地调试场景详细日志-v时挂载LoggingEventListener.Factory配合HttpLoggingInterceptor.Logger(::println)输出到标准输出从而打印 OkHttp 事件监听器级别的完整调用事件。请求结束后close()Main.kt会调用connectionPool.evictAll()关闭所有持久连接并shutdownNow()关闭 Dispatcher 的线程池确保原生镜像进程不会因后台线程而挂起。响应输出与日志体系响应体流式输出commonRun()internal/-MainCommon.kt是请求的执行主流程通过client.newCall(request).execute()同步执行请求若指定了-i/--include先打印状态行复用 OkHttp 内部的StatusLine.get(response)和全部响应头借助 okio 把响应体流式写入System.out每次取当前 buffer 大小写入并 flush因此大响应体不会一次性载入内存行为与 curl 的流式输出一致异常时打印堆栈e.printStackTrace()finally中调用close()释放资源。分级日志verbose、HTTP/2 帧与 SSL 调试日志体系由 logging/LoggingUtil.kt 统一配置基于 JDK 的java.util.logging-v/--verbose将根 Logger 级别设为ALL并挂上单行格式化器OneLineLogFormat时间精确到毫秒、异常带完整堆栈见 OneLineLogFormat.kt同时把jdk.event.security、org.conscrypt等 Logger 收敛到INFO避免噪音淹没关键信息--frames将 OkHttp HTTP/2 实现所在的okhttp3.internal.http2.Http2Logger 级别提升到FINE配合极简的MessageFormatter仅输出消息本身见 MessageFormatter.kt把 HTTP/2 帧日志定向输出到 STDERR——这正是调试 HTTP/2 行为时最直接的手段--sslDebug设置javax.net.ssl系统属性并启用javax.net.sslLogger 的FINEST级别其自定义ConsoleHandler还会把 SSL 握手参数打印到 STDERR用于排查 TLS 握手问题。三个开关可组合使用且只有在至少启用其中一个时才会重置 LogManager 并挂载 Handler保证默认模式下输出干净、只有响应体本身。典型使用场景综合 OkCurl 的能力边界它适合以下场景HTTP/2 协议验证用--frames观察请求/响应对应的 HTTP/2 帧序列验证服务器对 OkHttp HTTP/2 实现的兼容性OkHttp 引擎冒烟测试在接入 OkHttp 的应用之外快速确认某个 URL 在 OkHttp 引擎下的行为重定向、超时、TLS、连接复用与 curl 的对照实验由于 CLI 语义刻意向 curl 对齐可以很方便地对同一服务器分别用 curl 与 OkCurl 发起请求对比不同 HTTP 客户端栈的行为差异本地 HTTPS 调试借助-k与--sslDebug访问自签名证书站点并排查握手细节。需要注意OkCurl 是 OkHttp 仓库内的开发/测试工具运行前必须准备 GraalVM 环境GRAALVM_HOME其能力范围也以 okcurl/README.md 及上文所列源码为准不宜将其当作覆盖 curl 全部特性的通用生产脚本工具。结语OkCurl 是观察 OkHttp 引擎的一个绝佳窗口几十行 Kotlin 代码 Clikt 参数绑定 GraalVM 原生编译就构成了一个语义贴近 curl、行为完全由 OkHttp 驱动的命令行 HTTP 客户端。无论是验证 HTTP/2 帧、调试 TLS 握手还是快速对照不同客户端实现okcurl/README.md 给出的GRAALVM_HOME./okcurl两步流程都能让你在几分钟内跑起来并借助本文梳理的参数语义与源码路径把每个选项背后的行为看个通透。【免费下载链接】okhttpA meticulous HTTP client for the JVM, Android, and GraalVM.项目地址: https://gitcode.com/gh_mirrors/okh/okhttp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考