refactor: 移除 soulsoft_serialization / soulsoft_net_http 依赖——全部 HTTP 改 stdx.net.http
- SimApiStorage 4 处 S3 请求(PUT 上传/HEAD 检桶/PUT 建桶/POST 删除)改 stdx ClientBuilder/HttpRequestBuilder - SimApiAuthCenter.verifySign 改 stdx(post + body + 读响应) - cjpm.toml 删除 soulsoft_serialization、soulsoft_net_http(soulsoft web 栈传递依赖提供序列化) - S3 全链路实测通过(上传/预签名/删除)
This commit is contained in:
@@ -14,14 +14,14 @@
|
||||
package simapi.helpers
|
||||
|
||||
import std.collection.*
|
||||
import std.io.*
|
||||
import std.time.*
|
||||
import stdx.crypto.digest.*
|
||||
import stdx.encoding.base64.*
|
||||
import stdx.encoding.hex.*
|
||||
import stdx.net.http.*
|
||||
import stdx.net.tls.*
|
||||
import stdx.net.tls.common.*
|
||||
import soulsoft_net_http.{ByteArrayContent, HttpClient, HttpRequestMessage}
|
||||
import soulsoft_net_http.{HttpMethod as NetHttpMethod}
|
||||
import soulsoft_web_http.*
|
||||
import simapi.configurations.*
|
||||
|
||||
@@ -238,17 +238,19 @@ public class SimApiStorage {
|
||||
toHexString(hmacSha256(buildSigningKey(dateStamp), stringToSign.toArray())))
|
||||
let client = createClient()
|
||||
try {
|
||||
let request = HttpRequestMessage(NetHttpMethod.Put, "${_endpoint}${canonicalUri}")
|
||||
request.headers.add("x-amz-content-sha256", payloadHash)
|
||||
request.headers.add("x-amz-date", amzDate)
|
||||
request.headers.add("Authorization", authorization)
|
||||
let content = ByteArrayContent(data)
|
||||
content.headers.add("Content-Type", contentType)
|
||||
request.content = content
|
||||
let request = HttpRequestBuilder().
|
||||
put().
|
||||
url("${_endpoint}${canonicalUri}").
|
||||
header("x-amz-content-sha256", payloadHash).
|
||||
header("x-amz-date", amzDate).
|
||||
header("Authorization", authorization).
|
||||
header("Content-Type", contentType).
|
||||
body(data).
|
||||
build()
|
||||
let response = client.send(request)
|
||||
try {
|
||||
SimApiError.errorWhenFalse(response.isSuccessStatusCode, code: response.statusCode,
|
||||
message: "SimApiStorage 上传失败: HTTP ${response.statusCode}")
|
||||
SimApiError.errorWhenFalse(isSuccess(response.status), code: Int64(response.status),
|
||||
message: "SimApiStorage 上传失败: HTTP ${response.status}")
|
||||
} finally {
|
||||
response.close()
|
||||
}
|
||||
@@ -273,13 +275,16 @@ public class SimApiStorage {
|
||||
toHexString(hmacSha256(buildSigningKey(dateStamp), stringToSign.toArray())))
|
||||
let client = createClient()
|
||||
try {
|
||||
let request = HttpRequestMessage(NetHttpMethod.Head, "${_endpoint}${canonicalUri}")
|
||||
request.headers.add("x-amz-content-sha256", payloadHash)
|
||||
request.headers.add("x-amz-date", amzDate)
|
||||
request.headers.add("Authorization", authorization)
|
||||
let request = HttpRequestBuilder().
|
||||
head().
|
||||
url("${_endpoint}${canonicalUri}").
|
||||
header("x-amz-content-sha256", payloadHash).
|
||||
header("x-amz-date", amzDate).
|
||||
header("Authorization", authorization).
|
||||
build()
|
||||
let response = client.send(request)
|
||||
try {
|
||||
response.statusCode == 200
|
||||
response.status == 200
|
||||
} finally {
|
||||
response.close()
|
||||
}
|
||||
@@ -304,15 +309,18 @@ public class SimApiStorage {
|
||||
toHexString(hmacSha256(buildSigningKey(dateStamp), stringToSign.toArray())))
|
||||
let client = createClient()
|
||||
try {
|
||||
let request = HttpRequestMessage(NetHttpMethod.Put, "${_endpoint}${canonicalUri}")
|
||||
request.headers.add("x-amz-content-sha256", payloadHash)
|
||||
request.headers.add("x-amz-date", amzDate)
|
||||
request.headers.add("Authorization", authorization)
|
||||
request.content = ByteArrayContent(Array<Byte>(0, repeat: 0))
|
||||
let request = HttpRequestBuilder().
|
||||
put().
|
||||
url("${_endpoint}${canonicalUri}").
|
||||
header("x-amz-content-sha256", payloadHash).
|
||||
header("x-amz-date", amzDate).
|
||||
header("Authorization", authorization).
|
||||
body(Array<UInt8>(0, repeat: 0u8)).
|
||||
build()
|
||||
let response = client.send(request)
|
||||
try {
|
||||
SimApiError.errorWhenFalse(response.isSuccessStatusCode, code: response.statusCode,
|
||||
message: "SimApiStorage 创建桶失败: HTTP ${response.statusCode}")
|
||||
SimApiError.errorWhenFalse(isSuccess(response.status), code: Int64(response.status),
|
||||
message: "SimApiStorage 创建桶失败: HTTP ${response.status}")
|
||||
} finally {
|
||||
response.close()
|
||||
}
|
||||
@@ -347,20 +355,22 @@ public class SimApiStorage {
|
||||
toHexString(hmacSha256(buildSigningKey(dateStamp), stringToSign.toArray())))
|
||||
let client = createClient()
|
||||
try {
|
||||
let request = HttpRequestMessage(NetHttpMethod.Post, "${_endpoint}${canonicalUri}?${canonicalQuery}")
|
||||
request.headers.add("x-amz-content-sha256", payloadHash)
|
||||
request.headers.add("x-amz-date", amzDate)
|
||||
request.headers.add("Authorization", authorization)
|
||||
let contentMd5 = md5Base64(xml.toArray())
|
||||
let content = ByteArrayContent(xml.toArray())
|
||||
content.headers.add("Content-Type", "application/xml")
|
||||
// MinIO 的 DeleteObjects 强制要求 Content-Md5(缺失返回 MissingContentMD5)
|
||||
content.headers.add("Content-Md5", contentMd5)
|
||||
request.content = content
|
||||
let request = HttpRequestBuilder().
|
||||
post().
|
||||
url("${_endpoint}${canonicalUri}?${canonicalQuery}").
|
||||
header("x-amz-content-sha256", payloadHash).
|
||||
header("x-amz-date", amzDate).
|
||||
header("Authorization", authorization).
|
||||
header("Content-Type", "application/xml").
|
||||
// MinIO 的 DeleteObjects 强制要求 Content-Md5(缺失返回 MissingContentMD5)
|
||||
header("Content-Md5", contentMd5).
|
||||
body(xml).
|
||||
build()
|
||||
let response = client.send(request)
|
||||
try {
|
||||
SimApiError.errorWhenFalse(response.isSuccessStatusCode, code: response.statusCode,
|
||||
message: "SimApiStorage 批量删除失败: HTTP ${response.statusCode}")
|
||||
SimApiError.errorWhenFalse(isSuccess(response.status), code: Int64(response.status),
|
||||
message: "SimApiStorage 批量删除失败: HTTP ${response.status}")
|
||||
} finally {
|
||||
response.close()
|
||||
}
|
||||
@@ -381,19 +391,25 @@ public class SimApiStorage {
|
||||
hmacSha256(kService, "aws4_request".toArray())
|
||||
}
|
||||
|
||||
private func createClient(): HttpClient {
|
||||
HttpClient.create { builder =>
|
||||
builder.noProxy()
|
||||
if (_useSsl) {
|
||||
var tls = TlsClientConfig()
|
||||
tls.verifyMode = CertificateVerifyMode.TrustAll
|
||||
let host = extractHost(_endpoint)
|
||||
if (!host.isEmpty()) {
|
||||
tls.serverName = Some(host)
|
||||
}
|
||||
builder.tlsConfig(tls)
|
||||
private func createClient(): Client {
|
||||
let builder = ClientBuilder().
|
||||
noProxy().
|
||||
readTimeout(Duration.second * 60)
|
||||
if (_useSsl) {
|
||||
var tls = TlsClientConfig()
|
||||
tls.verifyMode = CertificateVerifyMode.TrustAll
|
||||
let host = extractHost(_endpoint)
|
||||
if (!host.isEmpty()) {
|
||||
tls.serverName = Some(host)
|
||||
}
|
||||
return builder.tlsConfig(tls).build()
|
||||
}
|
||||
builder.build()
|
||||
}
|
||||
|
||||
/// 2xx 视为成功
|
||||
private static func isSuccess(status: UInt16): Bool {
|
||||
status >= 200 && status < 300
|
||||
}
|
||||
|
||||
private func checkPath(path: String): Unit {
|
||||
|
||||
Reference in New Issue
Block a user