alibabacloud-gateway-pop/swift/Sources/AlibabacloudGatewayPOP/Client.swift (310 lines of code) (raw):
import Foundation
import Tea
import AlibabacloudGatewaySPI
import AlibabaCloudCredentials
import TeaUtils
import AlibabaCloudOpenApiUtil
import AlibabacloudEndpointUtil
import DarabonbaEncodeUtil
import DarabonbaSignatureUtil
import DarabonbaString
import DarabonbaMap
import DarabonbaArray
open class Client : AlibabacloudGatewaySPI.Client {
public var _endpointSuffix: String?
public var _signatureTypePrefix: String?
public var _signPrefix: String?
public var _sha256: String?
public var _sm3: String?
public override init() throws {
try super.init()
self._signatureTypePrefix = "ACS4-"
self._signPrefix = "aliyun_v4"
self._endpointSuffix = "aliyuncs.com"
self._sha256 = (self._signatureTypePrefix ?? "") + "HMAC-SHA256"
self._sm3 = (self._signatureTypePrefix ?? "") + "HMAC-SM3"
}
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
public func modifyConfiguration(_ context: AlibabacloudGatewaySPI.InterceptorContext, _ attributeMap: AlibabacloudGatewaySPI.AttributeMap) async throws -> Void {
var request: AlibabacloudGatewaySPI.InterceptorContext.Request = context.request!
var config: AlibabacloudGatewaySPI.InterceptorContext.Configuration = context.configuration!
var attributes: String = attributeMap.key ?? [:]
if (!TeaUtils.Client.isUnset(attributes)) {
self._signatureTypePrefix = attributes["signatureTypePrefix"]
self._signPrefix = attributes["signPrefix"]
self._endpointSuffix = attributes["endpointSuffix"]
self._sha256 = (self._signatureTypePrefix ?? "") + "HMAC-SHA256"
self._sm3 = (self._signatureTypePrefix ?? "") + "HMAC-SM3"
}
config.endpoint = try getEndpoint(request.productId ?? "", config.regionId ?? "", config.endpointRule ?? "", config.network ?? "", config.suffix ?? "", config.endpointMap ?? [:], config.endpoint ?? "")
}
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
public func modifyRequest(_ context: AlibabacloudGatewaySPI.InterceptorContext, _ attributeMap: AlibabacloudGatewaySPI.AttributeMap) async throws -> Void {
var request: AlibabacloudGatewaySPI.InterceptorContext.Request = context.request!
var config: AlibabacloudGatewaySPI.InterceptorContext.Configuration = context.configuration!
var date: String = AlibabaCloudOpenApiUtil.Client.getTimestamp()
request.headers = Tea.TeaConverter.merge([
"host": config.endpoint ?? "",
"x-acs-version": request.version ?? "",
"x-acs-action": request.action ?? "",
"user-agent": request.userAgent ?? "",
"x-acs-date": date as! String,
"x-acs-signature-nonce": TeaUtils.Client.getNonce(),
"accept": "application/json"
], request.headers ?? [:])
var signatureAlgorithm: String = TeaUtils.Client.defaultString(request.signatureAlgorithm, self._sha256)
var hashedRequestPayload: String = DarabonbaEncodeUtil.Client.hexEncode(DarabonbaEncodeUtil.Client.hash(TeaUtils.Client.toBytes(""), signatureAlgorithm))
if (!TeaUtils.Client.isUnset(request.stream)) {
var tmp: [UInt8] = try await TeaUtils.Client.readAsBytes(request.stream)
hashedRequestPayload = DarabonbaEncodeUtil.Client.hexEncode(DarabonbaEncodeUtil.Client.hash(tmp, signatureAlgorithm))
request.stream = Tea.TeaCore.toReadable(tmp)
request.headers!["content-type"] = "application/octet-stream";
}
else {
if (!TeaUtils.Client.isUnset(request.body)) {
if (TeaUtils.Client.equalString(request.reqBodyType, "json")) {
var jsonObj: String = TeaUtils.Client.toJSONString(request.body)
hashedRequestPayload = DarabonbaEncodeUtil.Client.hexEncode(DarabonbaEncodeUtil.Client.hash(TeaUtils.Client.toBytes(jsonObj), signatureAlgorithm))
request.stream = Tea.TeaCore.toReadable(jsonObj)
request.headers!["content-type"] = "application/json; charset=utf-8";
}
else {
var m: [String: Any] = try TeaUtils.Client.assertAsMap(request.body)
var formObj: String = AlibabaCloudOpenApiUtil.Client.toForm(m)
hashedRequestPayload = DarabonbaEncodeUtil.Client.hexEncode(DarabonbaEncodeUtil.Client.hash(TeaUtils.Client.toBytes(formObj), signatureAlgorithm))
request.stream = Tea.TeaCore.toReadable(formObj)
request.headers!["content-type"] = "application/x-www-form-urlencoded";
}
}
}
if (TeaUtils.Client.equalString(signatureAlgorithm, self._sm3)) {
request.headers!["x-acs-content-sm3"] = hashedRequestPayload;
}
else {
request.headers!["x-acs-content-sha256"] = hashedRequestPayload;
}
if (!TeaUtils.Client.equalString(request.authType, "Anonymous")) {
var credential: AlibabaCloudCredentials.Client = request.credential!
if (TeaUtils.Client.isUnset(credential)) {
throw Tea.ReuqestError([
"code": "ParameterMissing",
"message": "'config.credential' can not be unset"
])
}
var credentialModel: AlibabaCloudCredentials.CredentialModel = try await credential.getCredential()
if (!TeaUtils.Client.empty(credentialModel.providerName)) {
request.headers!["x-acs-credentials-provider"] = credentialModel.providerName;
}
var authType: String = credentialModel.type ?? ""
if (TeaUtils.Client.equalString(authType, "bearer")) {
var bearerToken: String = credential.getBearerToken()
request.headers!["x-acs-bearer-token"] = bearerToken;
request.headers!["x-acs-signature-type"] = "BEARERTOKEN";
request.headers!["Authorization"] = "Bearer " + (bearerToken as! String);
}
else if (TeaUtils.Client.equalString(authType, "id_token")) {
var idToken: String = credentialModel.securityToken ?? ""
request.headers!["x-acs-zero-trust-idtoken"] = idToken;
}
else {
var accessKeyId: String = credentialModel.accessKeyId ?? ""
var accessKeySecret: String = credentialModel.accessKeySecret ?? ""
var securityToken: String = credentialModel.securityToken ?? ""
if (!TeaUtils.Client.empty(securityToken)) {
request.headers!["x-acs-accesskey-id"] = accessKeyId;
request.headers!["x-acs-security-token"] = securityToken;
}
var dateNew: String = DarabonbaString.Client.subString(date, 0, 10)
dateNew = DarabonbaString.Client.replace(dateNew, "-", "", nil)
var region: String = getRegion(request.productId ?? "", config.endpoint ?? "", config.regionId ?? "")
var signingkey: [UInt8] = try await getSigningkey(signatureAlgorithm as! String, accessKeySecret as! String, request.productId ?? "", region as! String, dateNew as! String)
request.headers!["Authorization"] = try await getAuthorization(request.pathname ?? "", request.method ?? "", request.query ?? [:], request.headers ?? [:], signatureAlgorithm as! String, hashedRequestPayload as! String, accessKeyId as! String, signingkey as! [UInt8], request.productId ?? "", region as! String, dateNew as! String);
}
}
}
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
public func modifyResponse(_ context: AlibabacloudGatewaySPI.InterceptorContext, _ attributeMap: AlibabacloudGatewaySPI.AttributeMap) async throws -> Void {
var request: AlibabacloudGatewaySPI.InterceptorContext.Request = context.request!
var response: AlibabacloudGatewaySPI.InterceptorContext.Response = context.response!
if (TeaUtils.Client.is4xx(response.statusCode) || TeaUtils.Client.is5xx(response.statusCode)) {
var _res: Any = try await TeaUtils.Client.readAsJSON(response.body)
var err: [String: Any] = try TeaUtils.Client.assertAsMap(_res)
var requestId: Any = defaultAny(err["RequestId"]!, err["requestId"]!)
if (!TeaUtils.Client.isUnset(response.headers!["x-acs-request-id"])) {
requestId = response.headers!["x-acs-request-id"] ?? ""
}
err["statusCode"] = response.statusCode
throw Tea.ReuqestError([
"code": String(defaultAny(err["Code"]!, err["code"]!)),
"message": "code: " + String(response.statusCode!) + ", " + String(defaultAny(err["Message"]!, err["message"]!)) + " request id: " + String(requestId as! Any),
"data": err as! [String: Any],
"description": String(defaultAny(err["Description"]!, err["description"]!)),
"accessDeniedDetail": defaultAny(err["AccessDeniedDetail"]!, err["accessDeniedDetail"]!)
])
}
if (TeaUtils.Client.equalNumber(response.statusCode, 204)) {
try await TeaUtils.Client.readAsString(response.body)
}
else if (TeaUtils.Client.equalString(request.bodyType, "binary")) {
response.deserializedBody = response.body
}
else if (TeaUtils.Client.equalString(request.bodyType, "byte")) {
var byt: [UInt8] = try await TeaUtils.Client.readAsBytes(response.body)
response.deserializedBody = byt
}
else if (TeaUtils.Client.equalString(request.bodyType, "string")) {
var str: String = try await TeaUtils.Client.readAsString(response.body)
response.deserializedBody = str
}
else if (TeaUtils.Client.equalString(request.bodyType, "json")) {
var obj: Any = try await TeaUtils.Client.readAsJSON(response.body)
var res: [String: Any] = try TeaUtils.Client.assertAsMap(obj)
response.deserializedBody = res
}
else if (TeaUtils.Client.equalString(request.bodyType, "array")) {
var arr: Any = try await TeaUtils.Client.readAsJSON(response.body)
response.deserializedBody = arr
}
else {
response.deserializedBody = try await TeaUtils.Client.readAsString(response.body)
}
}
public func getEndpoint(_ productId: String, _ regionId: String, _ endpointRule: String, _ network: String, _ suffix: String, _ endpointMap: [String: String], _ endpoint: String) throws -> String {
if (!TeaUtils.Client.empty(endpoint)) {
return endpoint as! String
}
if (!TeaUtils.Client.isUnset(endpointMap) && !TeaUtils.Client.empty(endpointMap[regionId as! String])) {
return endpointMap[regionId as! String] ?? ""
}
return try AlibabacloudEndpointUtil.Client.getEndpointRules(productId, regionId, endpointRule, network, suffix)
}
public func defaultAny(_ inputValue: Any, _ defaultValue: Any) -> Any {
if (TeaUtils.Client.isUnset(inputValue)) {
return defaultValue as! Any
}
return inputValue as! Any
}
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
public func getAuthorization(_ pathname: String, _ method: String, _ query: [String: String], _ headers: [String: String], _ signatureAlgorithm: String, _ payload: String, _ ak: String, _ signingkey: [UInt8], _ product: String, _ region: String, _ date: String) async throws -> String {
var signature: String = try await getSignature(pathname as! String, method as! String, query as! [String: String], headers as! [String: String], signatureAlgorithm as! String, payload as! String, signingkey as! [UInt8])
var signedHeaders: [String] = try await getSignedHeaders(headers as! [String: String])
var signedHeadersStr: String = DarabonbaArray.Client.join(signedHeaders, ";")
return (signatureAlgorithm as! String) + " Credential=" + (ak as! String) + "/" + (date as! String) + "/" + (region as! String) + "/" + (product as! String) + "/" + (self._signPrefix ?? "") + "_request,SignedHeaders=" + (signedHeadersStr as! String) + ",Signature=" + (signature as! String)
}
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
public func getSignature(_ pathname: String, _ method: String, _ query: [String: String], _ headers: [String: String], _ signatureAlgorithm: String, _ payload: String, _ signingkey: [UInt8]) async throws -> String {
var canonicalURI: String = "/"
if (!TeaUtils.Client.empty(pathname)) {
canonicalURI = pathname as! String
}
var stringToSign: String = ""
var canonicalizedResource: String = try await buildCanonicalizedResource(query as! [String: String])
var canonicalizedHeaders: String = try await buildCanonicalizedHeaders(headers as! [String: String])
var signedHeaders: [String] = try await getSignedHeaders(headers as! [String: String])
var signedHeadersStr: String = DarabonbaArray.Client.join(signedHeaders, ";")
stringToSign = (method as! String) + "\n" + (canonicalURI as! String) + "\n" + (canonicalizedResource as! String) + "\n" + (canonicalizedHeaders as! String) + "\n" + (signedHeadersStr as! String) + "\n" + (payload as! String)
var hex: String = DarabonbaEncodeUtil.Client.hexEncode(DarabonbaEncodeUtil.Client.hash(TeaUtils.Client.toBytes(stringToSign), signatureAlgorithm))
stringToSign = (signatureAlgorithm as! String) + "\n" + (hex as! String)
var signature: [UInt8] = TeaUtils.Client.toBytes("")
if (TeaUtils.Client.equalString(signatureAlgorithm, self._sha256)) {
signature = DarabonbaSignatureUtil.Client.HmacSHA256SignByBytes(stringToSign, signingkey)
}
else if (TeaUtils.Client.equalString(signatureAlgorithm, self._sm3)) {
signature = DarabonbaSignatureUtil.Client.HmacSM3SignByBytes(stringToSign, signingkey)
}
return DarabonbaEncodeUtil.Client.hexEncode(signature)
}
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
public func getSigningkey(_ signatureAlgorithm: String, _ secret: String, _ product: String, _ region: String, _ date: String) async throws -> [UInt8] {
var sc1: String = (self._signPrefix ?? "") + (secret as! String)
var sc2: [UInt8] = TeaUtils.Client.toBytes("")
if (TeaUtils.Client.equalString(signatureAlgorithm, self._sha256)) {
sc2 = DarabonbaSignatureUtil.Client.HmacSHA256Sign(date, sc1)
}
else if (TeaUtils.Client.equalString(signatureAlgorithm, self._sm3)) {
sc2 = DarabonbaSignatureUtil.Client.HmacSM3Sign(date, sc1)
}
var sc3: [UInt8] = TeaUtils.Client.toBytes("")
if (TeaUtils.Client.equalString(signatureAlgorithm, self._sha256)) {
sc3 = DarabonbaSignatureUtil.Client.HmacSHA256SignByBytes(region, sc2)
}
else if (TeaUtils.Client.equalString(signatureAlgorithm, self._sm3)) {
sc3 = DarabonbaSignatureUtil.Client.HmacSM3SignByBytes(region, sc2)
}
var sc4: [UInt8] = TeaUtils.Client.toBytes("")
if (TeaUtils.Client.equalString(signatureAlgorithm, self._sha256)) {
sc4 = DarabonbaSignatureUtil.Client.HmacSHA256SignByBytes(product, sc3)
}
else if (TeaUtils.Client.equalString(signatureAlgorithm, self._sm3)) {
sc4 = DarabonbaSignatureUtil.Client.HmacSM3SignByBytes(product, sc3)
}
var hmac: [UInt8] = TeaUtils.Client.toBytes("")
if (TeaUtils.Client.equalString(signatureAlgorithm, self._sha256)) {
hmac = DarabonbaSignatureUtil.Client.HmacSHA256SignByBytes((self._signPrefix ?? "") + "_request", sc4)
}
else if (TeaUtils.Client.equalString(signatureAlgorithm, self._sm3)) {
hmac = DarabonbaSignatureUtil.Client.HmacSM3SignByBytes((self._signPrefix ?? "") + "_request", sc4)
}
return hmac as! [UInt8]
}
public func getRegion(_ product: String, _ endpoint: String, _ regionId: String) -> String {
if (!TeaUtils.Client.empty(regionId)) {
return regionId as! String
}
var region: String = "center"
if (TeaUtils.Client.empty(product) || TeaUtils.Client.empty(endpoint)) {
return region as! String
}
var strs: [String] = DarabonbaString.Client.split(endpoint, ":", nil)
var withoutPort: String = strs[0]
var preRegion: String = DarabonbaString.Client.replace(withoutPort, "." + (self._endpointSuffix ?? ""), "", nil)
var nodes: [String] = DarabonbaString.Client.split(preRegion, ".", nil)
if (TeaUtils.Client.equalNumber(DarabonbaArray.Client.size(nodes), 2)) {
region = nodes[1]
}
return region as! String
}
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
public func buildCanonicalizedResource(_ query: [String: String]) async throws -> String {
var canonicalizedResource: String = ""
if (!TeaUtils.Client.isUnset(query)) {
var queryArray: [String] = DarabonbaMap.Client.keySet(query)
var sortedQueryArray: [String] = DarabonbaArray.Client.ascSort(queryArray)
var separator: String = ""
for key in sortedQueryArray {
canonicalizedResource = (canonicalizedResource as! String) + (separator as! String) + (DarabonbaEncodeUtil.Client.percentEncode(key))
if (!TeaUtils.Client.empty(query[key as! String])) {
canonicalizedResource = (canonicalizedResource as! String) + "=" + (DarabonbaEncodeUtil.Client.percentEncode(query[key as! String]))
}
separator = "&"
}
}
return canonicalizedResource as! String
}
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
public func buildCanonicalizedHeaders(_ headers: [String: String]) async throws -> String {
var canonicalizedHeaders: String = ""
var sortedHeaders: [String] = try await getSignedHeaders(headers as! [String: String])
for header in sortedHeaders {
canonicalizedHeaders = (canonicalizedHeaders as! String) + (header as! String) + ":" + (DarabonbaString.Client.trim(headers[header as! String])) + "\n"
}
return canonicalizedHeaders as! String
}
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
public func getSignedHeaders(_ headers: [String: String]) async throws -> [String] {
var headersArray: [String] = DarabonbaMap.Client.keySet(headers)
var sortedHeadersArray: [String] = DarabonbaArray.Client.ascSort(headersArray)
var tmp: String = ""
var separator: String = ""
for key in sortedHeadersArray {
var lowerKey: String = DarabonbaString.Client.toLower(key)
if (DarabonbaString.Client.hasPrefix(lowerKey, "x-acs-") || DarabonbaString.Client.equals(lowerKey, "host") || DarabonbaString.Client.equals(lowerKey, "content-type")) {
if (!DarabonbaString.Client.contains(tmp, lowerKey)) {
tmp = (tmp as! String) + (separator as! String) + (lowerKey as! String)
separator = ";"
}
}
}
return DarabonbaString.Client.split(tmp, ";", nil)
}
}