refactor: SimApiHttpClient 改用 stdx.net.http——不再依赖 soulsoft_net_http

- query<T> 用 stdx.net.http ClientBuilder/HttpRequestBuilder/Client.send
  (等价 .NET HttpClient,替代 soulsoft_net_http.HttpClient)
- TLS 配置用 stdx TlsClientConfig(TrustAll + SNI 域名)
- 响应读取:status(UInt16) 2xx 判断 + InputStream 读 body
- 去掉 import soulsoft_net_http
- 端到端验证:stdx client 请求本机服务读响应正常
This commit is contained in:
2026-08-18 01:29:02 +08:00
parent 9c2e0ae0e3
commit 5c30f201ad
2 changed files with 56 additions and 30 deletions
+12 -12
View File
@@ -1,20 +1,20 @@
version = 0
[requires]
soulsoft_web_http = {version = "1.0.20260528"}
soulsoft_web_cors = {version = "1.0.20260528"}
soulsoft_extensions_options_configuration = {version = "1.0.20260528"}
soulsoft_extensions_logging = {version = "1.0.20260528"}
soulsoft_web_routing = {version = "1.0.20260528"}
soulsoft_extensions_logging_console = {version = "1.0.20260528"}
soulsoft_extensions_hosting = {version = "1.0.20260528"}
soulsoft_extensions_configuration = {version = "1.0.20260528"}
soulsoft_extensions_logging_configuration = {version = "1.0.20260528"}
soulsoft_web_http = {version = "1.0.20260528"}
soulsoft_extensions_options_configuration = {version = "1.0.20260528"}
soulsoft_web_routing = {version = "1.0.20260528"}
soulsoft_web_hosting = {version = "1.0.20260528"}
soulsoft_extensions_injection = {version = "1.0.20260528"}
soulsoft_net_http = {version = "1.0.20260528"}
soulsoft_extensions_options = {version = "1.0.20260528"}
soulsoft_extensions_logging = {version = "1.0.20260528"}
soulsoft_web_mvc = {version = "1.0.20260528"}
soulsoft_serialization = {version = "1.0.20260528"}
soulsoft_net_http = {version = "1.0.20260528"}
soulsoft_extensions_logging_console = {version = "1.0.20260528"}
soulsoft_identity_claims = {version = "1.0.20260528"}
redis = {version = "1.0.20260627"}
soulsoft_serialization = {version = "1.0.20260528"}
soulsoft_extensions_logging_configuration = {version = "1.0.20260528"}
soulsoft_extensions_configuration = {version = "1.0.20260528"}
soulsoft_extensions_options = {version = "1.0.20260528"}
soulsoft_web_cors = {version = "1.0.20260528"}
soulsoft_extensions_injection = {version = "1.0.20260528"}
+44 -18
View File
@@ -7,10 +7,9 @@ package simapi.helpers
import std.collection.*
import std.io.*
import stdx.net.http.*
import stdx.net.tls.*
import stdx.net.tls.common.*
import soulsoft_net_http.{HttpClient, HttpRequestMessage, JsonContent}
import soulsoft_net_http.{HttpMethod as NetHttpMethod}
import simapi_serialization.*
import simapi.communications.*
import simapi.configurations.*
@@ -19,7 +18,7 @@ import simapi.exceptions.*
/**
* HTTP 客户端:用于调用其他带签名/AES 的 SimApi 服务。
* 对齐 C# 的 SimApi.Helpers.SimApiHttpClient
* - 内部使用 soulsoft_net_http 的 HttpClient(等价 .NET 的 System.Net.Http.HttpClient
* - 内部使用 stdx.net.http 的 HttpClient(等价 .NET 的 System.Net.Http.HttpClient
* - 返回泛型 T(反序列化响应 body 的 data 字段),不再返回 String
* @param T 响应 data 的数据类型(任意类,simapi_serialization 反射反序列化)。
*/
@@ -112,24 +111,23 @@ public open class SimApiHttpClient {
* 反序列化使用 simapi_serializationDeserialize<T> 免约束)。
*/
private func query<T>(url: String, body: String): T {
let client = HttpClient.create { builder =>
builder.noProxy()
// 支持 https:配置 TLS(信任所有证书 + SNI 域名)
var tls = TlsClientConfig()
tls.verifyMode = CertificateVerifyMode.TrustAll
let host = extractHost(url)
if (!host.isEmpty()) {
tls.serverName = Some(host)
}
builder.tlsConfig(tls)
}
let client = ClientBuilder().
noProxy().
tlsConfig(buildTlsConfig(url)).
readTimeout(Duration.second * 30).
build()
try {
let request = HttpRequestMessage(NetHttpMethod.Post, url)
request.content = JsonContent.create(body)
let request = HttpRequestBuilder().
post().
url(url).
header("Content-Type", "application/json").
body(body).
build()
let response = client.send(request)
try {
SimApiError.errorWhenFalse(response.isSuccessStatusCode, code: response.statusCode, message: "HTTP ERROR: ${response.statusCode}")
let json = response.content.readAsString()
SimApiError.errorWhenFalse(isSuccess(response.status), code: Int64(response.status),
message: "HTTP ERROR: ${response.status}")
let json = readBodyText(response.body)
let result = JsonSerializer.Deserialize<SimApiResponse<T>>(json)
SimApiError.errorWhen(result.code != 200, code: result.code, message: result.message)
return result.data.getOrThrow()
@@ -141,6 +139,34 @@ public open class SimApiHttpClient {
}
}
/// 2xx 视为成功
private static func isSuccess(status: UInt16): Bool {
status >= 200 && status < 300
}
/// 读取响应体 InputStream 为字符串
private static func readBodyText(body: InputStream): String {
var buffer = Array<Byte>(4096, repeat: 0)
var sb = StringBuilder()
var read = body.read(buffer)
while (read > 0) {
sb.appendFromUtf8(buffer.slice(0, read))
read = body.read(buffer)
}
sb.toString()
}
/// 构建 TLS 配置:信任所有证书 + SNI 域名
private static func buildTlsConfig(url: String): TlsClientConfig {
var tls = TlsClientConfig()
tls.verifyMode = CertificateVerifyMode.TrustAll
let host = extractHost(url)
if (!host.isEmpty()) {
tls.serverName = Some(host)
}
tls
}
private func aesEncrypt(plain: String): String {
// 对齐 C#SimApiAesUtil.Encrypt(plain, AppKey)AES-256-CBC + PKCS7Base64(IV + 密文)
SimApiAesUtil.encrypt(plain, appKey)