From 050686f7be1fe4d024ad772cd5d29ff78b2066d5 Mon Sep 17 00:00:00 2001 From: yndu13 Date: Fri, 15 Aug 2025 11:23:52 +0800 Subject: [PATCH] [Gateway POP]fix: resolve canonicalized headers and response headers --- alibabacloud-gateway-pop/Teafile | 3 +- .../csharp/core/Client.cs | 47 +++++++++++++++++-- .../csharp/core/client.csproj | 1 + .../golang/client/client.go | 47 +++++++++++++++---- alibabacloud-gateway-pop/golang/go.mod | 4 +- alibabacloud-gateway-pop/golang/go.sum | 5 ++ alibabacloud-gateway-pop/java/pom.xml | 9 +++- .../java/com/aliyun/gateway/pop/Client.java | 28 +++++++++-- alibabacloud-gateway-pop/main.tea | 28 +++++++++-- alibabacloud-gateway-pop/php/composer.json | 3 +- alibabacloud-gateway-pop/php/src/Client.php | 29 ++++++++++-- .../python/alibabacloud_gateway_pop/client.py | 34 ++++++++++++-- alibabacloud-gateway-pop/python/setup.py | 13 +++-- alibabacloud-gateway-pop/ts/package.json | 3 +- alibabacloud-gateway-pop/ts/src/client.ts | 30 ++++++++++-- 15 files changed, 242 insertions(+), 42 deletions(-) diff --git a/alibabacloud-gateway-pop/Teafile b/alibabacloud-gateway-pop/Teafile index bda8e7cc..8c4deb34 100644 --- a/alibabacloud-gateway-pop/Teafile +++ b/alibabacloud-gateway-pop/Teafile @@ -19,7 +19,8 @@ "SignatureUtil": "darabonba:SignatureUtil:*", "String": "darabonba:String:*", "Map": "darabonba:Map:*", - "Array": "darabonba:Array:*" + "Array": "darabonba:Array:*", + "XML": "darabonba:XML:*" }, "releases": { "ts": "@alicloud/gateway-pop:^0.0.9", diff --git a/alibabacloud-gateway-pop/csharp/core/Client.cs b/alibabacloud-gateway-pop/csharp/core/Client.cs index f908dfdf..faf76a3b 100644 --- a/alibabacloud-gateway-pop/csharp/core/Client.cs +++ b/alibabacloud-gateway-pop/csharp/core/Client.cs @@ -298,8 +298,18 @@ public void ModifyResponse(AlibabaCloud.GatewaySpi.Models.InterceptorContext con AlibabaCloud.GatewaySpi.Models.InterceptorContext.InterceptorContextResponse response = context.Response; if (AlibabaCloud.TeaUtil.Common.Is4xx(response.StatusCode) || AlibabaCloud.TeaUtil.Common.Is5xx(response.StatusCode)) { - object _res = AlibabaCloud.TeaUtil.Common.ReadAsJSON(response.Body); - Dictionary err = AlibabaCloud.TeaUtil.Common.AssertAsMap(_res); + Dictionary err = new Dictionary(){}; + if (!AlibabaCloud.TeaUtil.Common.IsUnset(response.Headers.Get("content-type")) && AlibabaCloud.DarabonbaString.StringUtil.Contains(response.Headers.Get("content-type"), "text/xml")) + { + string _str = AlibabaCloud.TeaUtil.Common.ReadAsString(response.Body); + Dictionary respMap = AlibabaCloud.TeaXML.Client.ParseXml(_str, null); + err = AlibabaCloud.TeaUtil.Common.AssertAsMap(respMap.Get("Error")); + } + else + { + object _res = AlibabaCloud.TeaUtil.Common.ReadAsJSON(response.Body); + err = AlibabaCloud.TeaUtil.Common.AssertAsMap(_res); + } object requestId = DefaultAny(err.Get("RequestId"), err.Get("requestId")); if (!AlibabaCloud.TeaUtil.Common.IsUnset(response.Headers.Get("x-acs-request-id"))) { @@ -356,8 +366,18 @@ public async Task ModifyResponseAsync(AlibabaCloud.GatewaySpi.Models.Interceptor AlibabaCloud.GatewaySpi.Models.InterceptorContext.InterceptorContextResponse response = context.Response; if (AlibabaCloud.TeaUtil.Common.Is4xx(response.StatusCode) || AlibabaCloud.TeaUtil.Common.Is5xx(response.StatusCode)) { - object _res = AlibabaCloud.TeaUtil.Common.ReadAsJSON(response.Body); - Dictionary err = AlibabaCloud.TeaUtil.Common.AssertAsMap(_res); + Dictionary err = new Dictionary(){}; + if (!AlibabaCloud.TeaUtil.Common.IsUnset(response.Headers.Get("content-type")) && AlibabaCloud.DarabonbaString.StringUtil.Contains(response.Headers.Get("content-type"), "text/xml")) + { + string _str = AlibabaCloud.TeaUtil.Common.ReadAsString(response.Body); + Dictionary respMap = AlibabaCloud.TeaXML.Client.ParseXml(_str, null); + err = AlibabaCloud.TeaUtil.Common.AssertAsMap(respMap.Get("Error")); + } + else + { + object _res = AlibabaCloud.TeaUtil.Common.ReadAsJSON(response.Body); + err = AlibabaCloud.TeaUtil.Common.AssertAsMap(_res); + } object requestId = DefaultAny(err.Get("RequestId"), err.Get("requestId")); if (!AlibabaCloud.TeaUtil.Common.IsUnset(response.Headers.Get("x-acs-request-id"))) { @@ -552,11 +572,28 @@ public string BuildCanonicalizedResource(Dictionary query) public string BuildCanonicalizedHeaders(Dictionary headers) { + // lower header key + List headersArray = AlibabaCloud.DarabonbaMap.MapUtil.KeySet(headers); + Dictionary newHeaders = new Dictionary(){}; + string tmp = ""; + + foreach (var key in headersArray) { + string lowerKey = AlibabaCloud.DarabonbaString.StringUtil.ToLower(key); + if (!AlibabaCloud.DarabonbaString.StringUtil.Contains(tmp, lowerKey)) + { + tmp = "" + tmp + "," + lowerKey; + newHeaders[lowerKey] = AlibabaCloud.DarabonbaString.StringUtil.Trim(headers.Get(key)); + } + else + { + newHeaders[lowerKey] = "" + newHeaders.Get(lowerKey) + "," + AlibabaCloud.DarabonbaString.StringUtil.Trim(headers.Get(key)); + } + } string canonicalizedHeaders = ""; List sortedHeaders = GetSignedHeaders(headers); foreach (var header in sortedHeaders) { - canonicalizedHeaders = "" + canonicalizedHeaders + header + ":" + AlibabaCloud.DarabonbaString.StringUtil.Trim(headers.Get(header)) + "\n"; + canonicalizedHeaders = "" + canonicalizedHeaders + header + ":" + newHeaders.Get(header) + "\n"; } return canonicalizedHeaders; } diff --git a/alibabacloud-gateway-pop/csharp/core/client.csproj b/alibabacloud-gateway-pop/csharp/core/client.csproj index 2d429873..c75b90a6 100644 --- a/alibabacloud-gateway-pop/csharp/core/client.csproj +++ b/alibabacloud-gateway-pop/csharp/core/client.csproj @@ -51,5 +51,6 @@ + \ No newline at end of file diff --git a/alibabacloud-gateway-pop/golang/client/client.go b/alibabacloud-gateway-pop/golang/client/client.go index 5678b908..fb98b164 100644 --- a/alibabacloud-gateway-pop/golang/client/client.go +++ b/alibabacloud-gateway-pop/golang/client/client.go @@ -11,6 +11,7 @@ import ( endpointutil "github.com/alibabacloud-go/endpoint-util/service" openapiutil "github.com/alibabacloud-go/openapi-util/service" util "github.com/alibabacloud-go/tea-utils/v2/service" + xml "github.com/alibabacloud-go/tea-xml/service" "github.com/alibabacloud-go/tea/tea" ) @@ -181,14 +182,30 @@ func (client *Client) ModifyResponse(context *spi.InterceptorContext, attributeM request := context.Request response := context.Response if tea.BoolValue(util.Is4xx(response.StatusCode)) || tea.BoolValue(util.Is5xx(response.StatusCode)) { - _res, _err := util.ReadAsJSON(response.Body) - if _err != nil { - return _err - } + err := map[string]interface{}{} + if !tea.BoolValue(util.IsUnset(response.Headers["content-type"])) && tea.BoolValue(string_.Contains(response.Headers["content-type"], tea.String("text/xml"))) { + _str, _err := util.ReadAsString(response.Body) + if _err != nil { + return _err + } + + respMap := xml.ParseXml(_str, nil) + err, _err = util.AssertAsMap(respMap["Error"]) + if _err != nil { + return _err + } + + } else { + _res, _err := util.ReadAsJSON(response.Body) + if _err != nil { + return _err + } + + err, _err = util.AssertAsMap(_res) + if _err != nil { + return _err + } - err, _err := util.AssertAsMap(_res) - if _err != nil { - return _err } requestId := client.DefaultAny(err["RequestId"], err["requestId"]) @@ -400,10 +417,24 @@ func (client *Client) BuildCanonicalizedResource(query map[string]*string) (_res } func (client *Client) BuildCanonicalizedHeaders(headers map[string]*string) (_result *string) { + // lower header key + headersArray := map_.KeySet(headers) + newHeaders := make(map[string]*string) + tmp := tea.String("") + for _, key := range headersArray { + lowerKey := string_.ToLower(key) + if !tea.BoolValue(string_.Contains(tmp, lowerKey)) { + tmp = tea.String(tea.StringValue(tmp) + "," + tea.StringValue(lowerKey)) + newHeaders[tea.StringValue(lowerKey)] = string_.Trim(headers[tea.StringValue(key)]) + } else { + newHeaders[tea.StringValue(lowerKey)] = tea.String(tea.StringValue(newHeaders[tea.StringValue(lowerKey)]) + "," + tea.StringValue(string_.Trim(headers[tea.StringValue(key)]))) + } + + } canonicalizedHeaders := tea.String("") sortedHeaders := client.GetSignedHeaders(headers) for _, header := range sortedHeaders { - canonicalizedHeaders = tea.String(tea.StringValue(canonicalizedHeaders) + tea.StringValue(header) + ":" + tea.StringValue(string_.Trim(headers[tea.StringValue(header)])) + "\n") + canonicalizedHeaders = tea.String(tea.StringValue(canonicalizedHeaders) + tea.StringValue(header) + ":" + tea.StringValue(newHeaders[tea.StringValue(header)]) + "\n") } _result = canonicalizedHeaders return _result diff --git a/alibabacloud-gateway-pop/golang/go.mod b/alibabacloud-gateway-pop/golang/go.mod index f77c41e4..0716b304 100644 --- a/alibabacloud-gateway-pop/golang/go.mod +++ b/alibabacloud-gateway-pop/golang/go.mod @@ -13,7 +13,9 @@ require ( github.com/alibabacloud-go/openapi-util v0.1.1 github.com/alibabacloud-go/tea v1.2.2 github.com/alibabacloud-go/tea-utils/v2 v2.0.6 - github.com/aliyun/credentials-go v1.4.5 // indirect + github.com/alibabacloud-go/tea-xml v1.1.3 + github.com/aliyun/credentials-go v1.4.5 + github.com/clbanning/mxj/v2 v2.7.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect golang.org/x/net v0.23.0 // indirect diff --git a/alibabacloud-gateway-pop/golang/go.sum b/alibabacloud-gateway-pop/golang/go.sum index 1d4bfbfd..98132acc 100644 --- a/alibabacloud-gateway-pop/golang/go.sum +++ b/alibabacloud-gateway-pop/golang/go.sum @@ -40,6 +40,8 @@ github.com/alibabacloud-go/tea-utils/v2 v2.0.5 h1:EUakYEUAwr6L3wLT0vejIw2rc0IA1R github.com/alibabacloud-go/tea-utils/v2 v2.0.5/go.mod h1:dL6vbUT35E4F4bFTHL845eUloqaerYBYPsdWR2/jhe4= github.com/alibabacloud-go/tea-utils/v2 v2.0.6 h1:ZkmUlhlQbaDC+Eba/GARMPy6hKdCLiSke5RsN5LcyQ0= github.com/alibabacloud-go/tea-utils/v2 v2.0.6/go.mod h1:qxn986l+q33J5VkialKMqT/TTs3E+U9MJpd001iWQ9I= +github.com/alibabacloud-go/tea-xml v1.1.3 h1:7LYnm+JbOq2B+T/B0fHC4Ies4/FofC4zHzYtqw7dgt0= +github.com/alibabacloud-go/tea-xml v1.1.3/go.mod h1:Rq08vgCcCAjHyRi/M7xlHKUykZCEtyBy9+DPF6GgEu8= github.com/aliyun/credentials-go v1.1.2/go.mod h1:ozcZaMR5kLM7pwtCMEpVmQ242suV6qTJya2bDq4X1Tw= github.com/aliyun/credentials-go v1.3.1 h1:uq/0v7kWrxmoLGpqjx7vtQ/s03f0zR//0br/xWDTE28= github.com/aliyun/credentials-go v1.3.1/go.mod h1:8jKYhQuDawt8x2+fusqa1Y6mPxemTsBEN04dgcAcYz0= @@ -47,6 +49,9 @@ github.com/aliyun/credentials-go v1.3.6/go.mod h1:1LxUuX7L5YrZUWzBrRyk0SwSdH4OmP github.com/aliyun/credentials-go v1.4.5 h1:O76WYKgdy1oQYYiJkERjlA2dxGuvLRrzuO2ScrtGWSk= github.com/aliyun/credentials-go v1.4.5/go.mod h1:Jm6d+xIgwJVLVWT561vy67ZRP4lPTQxMbEYRuT2Ti1U= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/clbanning/mxj v1.8.4 h1:HuhwZtbyvyOw+3Z1AowPkU87JkJUSv751ELWaiTpj8I= +github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME= +github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/alibabacloud-gateway-pop/java/pom.xml b/alibabacloud-gateway-pop/java/pom.xml index e17643d5..b8c66a6b 100644 --- a/alibabacloud-gateway-pop/java/pom.xml +++ b/alibabacloud-gateway-pop/java/pom.xml @@ -42,8 +42,8 @@ scm:git:git://github.com/aliyun/alibabacloud-gateway.git - scm:git:git@github.com:aliyun/alibabacloud-gateway.git - https://github.com/aliyun/alibabacloud-gateway + scm:git:git@github.com:aliyun/alibabacloud-gateway.git + https://github.com/aliyun/alibabacloud-gateway @@ -108,6 +108,11 @@ 4.13.1 test + + com.aliyun + tea-xml + 0.1.6 + diff --git a/alibabacloud-gateway-pop/java/src/main/java/com/aliyun/gateway/pop/Client.java b/alibabacloud-gateway-pop/java/src/main/java/com/aliyun/gateway/pop/Client.java index 50a22c5c..d62195b3 100644 --- a/alibabacloud-gateway-pop/java/src/main/java/com/aliyun/gateway/pop/Client.java +++ b/alibabacloud-gateway-pop/java/src/main/java/com/aliyun/gateway/pop/Client.java @@ -139,8 +139,16 @@ public void modifyResponse(com.aliyun.gateway.spi.models.InterceptorContext cont com.aliyun.gateway.spi.models.InterceptorContext.InterceptorContextRequest request = context.request; com.aliyun.gateway.spi.models.InterceptorContext.InterceptorContextResponse response = context.response; if (com.aliyun.teautil.Common.is4xx(response.statusCode) || com.aliyun.teautil.Common.is5xx(response.statusCode)) { - Object _res = com.aliyun.teautil.Common.readAsJSON(response.body); - java.util.Map err = com.aliyun.teautil.Common.assertAsMap(_res); + java.util.Map err = new java.util.HashMap<>(); + if (!com.aliyun.teautil.Common.isUnset(response.headers.get("content-type")) && com.aliyun.darabonbastring.Client.contains(response.headers.get("content-type"), "text/xml")) { + String _str = com.aliyun.teautil.Common.readAsString(response.body); + java.util.Map respMap = com.aliyun.teaxml.Client.parseXml(_str, null); + err = com.aliyun.teautil.Common.assertAsMap(respMap.get("Error")); + } else { + Object _res = com.aliyun.teautil.Common.readAsJSON(response.body); + err = com.aliyun.teautil.Common.assertAsMap(_res); + } + Object requestId = this.defaultAny(err.get("RequestId"), err.get("requestId")); if (!com.aliyun.teautil.Common.isUnset(response.headers.get("x-acs-request-id"))) { requestId = response.headers.get("x-acs-request-id"); @@ -304,10 +312,24 @@ public String buildCanonicalizedResource(java.util.Map query) th } public String buildCanonicalizedHeaders(java.util.Map headers) throws Exception { + // lower header key + java.util.List headersArray = com.aliyun.darabonba.map.Client.keySet(headers); + java.util.Map newHeaders = new java.util.HashMap<>(); + String tmp = ""; + for (String key : headersArray) { + String lowerKey = com.aliyun.darabonbastring.Client.toLower(key); + if (!com.aliyun.darabonbastring.Client.contains(tmp, lowerKey)) { + tmp = "" + tmp + "," + lowerKey + ""; + newHeaders.put(lowerKey, com.aliyun.darabonbastring.Client.trim(headers.get(key))); + } else { + newHeaders.put(lowerKey, "" + newHeaders.get(lowerKey) + "," + com.aliyun.darabonbastring.Client.trim(headers.get(key)) + ""); + } + + } String canonicalizedHeaders = ""; java.util.List sortedHeaders = this.getSignedHeaders(headers); for (String header : sortedHeaders) { - canonicalizedHeaders = "" + canonicalizedHeaders + "" + header + ":" + com.aliyun.darabonbastring.Client.trim(headers.get(header)) + "\n"; + canonicalizedHeaders = "" + canonicalizedHeaders + "" + header + ":" + newHeaders.get(header) + "\n"; } return canonicalizedHeaders; } diff --git a/alibabacloud-gateway-pop/main.tea b/alibabacloud-gateway-pop/main.tea index c7364698..fcdd04a7 100644 --- a/alibabacloud-gateway-pop/main.tea +++ b/alibabacloud-gateway-pop/main.tea @@ -8,6 +8,7 @@ import SignatureUtil; import String; import Map; import Array; +import XML; extends SPI; @@ -140,8 +141,15 @@ async function modifyResponse(context: SPI.InterceptorContext, attributeMap: SPI var request = context.request; var response = context.response; if (Util.is4xx(response.statusCode) || Util.is5xx(response.statusCode)) { - var _res = Util.readAsJSON(response.body); - var err = Util.assertAsMap(_res); + var err : map[string]any = {}; + if (!Util.isUnset(response.headers.content-type) && String.contains(response.headers.content-type, 'text/xml')) { + var _str = Util.readAsString(response.body); + var respMap = XML.parseXml(_str, null); + err = Util.assertAsMap(respMap.Error); + } else { + var _res = Util.readAsJSON(response.body); + err = Util.assertAsMap(_res); + } var requestId = defaultAny(err.RequestId, err.requestId); if (!Util.isUnset(response.headers.x-acs-request-id)) { requestId = response.headers.x-acs-request-id; @@ -289,10 +297,24 @@ function buildCanonicalizedResource(query: map[string]string): string { } function buildCanonicalizedHeaders(headers: map[string]string): string { + // lower header key + var headersArray : [string] = Map.keySet(headers); + var newHeaders : map[string]string = {}; + var tmp : string = ''; + for(var key : headersArray) { + var lowerKey = String.toLower(key); + if (!String.contains(tmp, lowerKey)) { + tmp = `${tmp},${lowerKey}`; + newHeaders[lowerKey] = String.trim(headers[key]); + } else { + newHeaders[lowerKey] = `${newHeaders[lowerKey]},${String.trim(headers[key])}`; + } + } + var canonicalizedHeaders : string = ''; var sortedHeaders : [string] = getSignedHeaders(headers); for(var header : sortedHeaders) { - canonicalizedHeaders = `${canonicalizedHeaders}${header}:${String.trim(headers[header])}\n`; + canonicalizedHeaders = `${canonicalizedHeaders}${header}:${newHeaders[header]}\n`; } return canonicalizedHeaders; } diff --git a/alibabacloud-gateway-pop/php/composer.json b/alibabacloud-gateway-pop/php/composer.json index 207987fc..8977444a 100644 --- a/alibabacloud-gateway-pop/php/composer.json +++ b/alibabacloud-gateway-pop/php/composer.json @@ -20,7 +20,8 @@ "alibabacloud/darabonba-signature-util": "^0.0.4", "alibabacloud/darabonba-string": "^0.1.16", "alibabacloud/darabonba-map": "^0.0.1", - "alibabacloud/darabonba-array": "^0.1.0" + "alibabacloud/darabonba-array": "^0.1.0", + "alibabacloud/tea-xml": "^0.2" }, "autoload": { "psr-4": { diff --git a/alibabacloud-gateway-pop/php/src/Client.php b/alibabacloud-gateway-pop/php/src/Client.php index c2fe0a34..25ab876a 100644 --- a/alibabacloud-gateway-pop/php/src/Client.php +++ b/alibabacloud-gateway-pop/php/src/Client.php @@ -10,6 +10,7 @@ use AlibabaCloud\Tea\Tea; use AlibabaCloud\Darabonba\EncodeUtil\EncodeUtil; use AlibabaCloud\Darabonba\String\StringUtil; +use AlibabaCloud\Tea\XML\XML; use AlibabaCloud\Endpoint\Endpoint; use AlibabaCloud\Darabonba\ArrayUtil\ArrayUtil; use AlibabaCloud\Darabonba\SignatureUtil\SignatureUtil; @@ -130,7 +131,7 @@ public function modifyRequest($context, $attributeMap) } $authType = $credentialModel->type; if (Utils::equalString($authType, "bearer")) { - $bearerToken = $credential->getBearerToken(); + $bearerToken = $credentialModel->bearerToken; $request->headers["x-acs-bearer-token"] = $bearerToken; $request->headers["x-acs-signature-type"] = "BEARERTOKEN"; $request->headers["Authorization"] = "Bearer " . $bearerToken . ""; @@ -165,8 +166,15 @@ public function modifyResponse($context, $attributeMap) $request = $context->request; $response = $context->response; if (Utils::is4xx($response->statusCode) || Utils::is5xx($response->statusCode)) { - $_res = Utils::readAsJSON($response->body); - $err = Utils::assertAsMap($_res); + $err = []; + if (!Utils::isUnset(@$response->headers["content-type"]) && StringUtil::contains(@$response->headers["content-type"], "text/xml")) { + $_str = Utils::readAsString($response->body); + $respMap = XML::parseXml($_str, null); + $err = Utils::assertAsMap(@$respMap["Error"]); + } else { + $_res = Utils::readAsJSON($response->body); + $err = Utils::assertAsMap($_res); + } $requestId = $this->defaultAny(@$err["RequestId"], @$err["requestId"]); if (!Utils::isUnset(@$response->headers["x-acs-request-id"])) { $requestId = @$response->headers["x-acs-request-id"]; @@ -382,10 +390,23 @@ public function buildCanonicalizedResource($query) */ public function buildCanonicalizedHeaders($headers) { + // lower header key + $headersArray = MapUtil::keySet($headers); + $newHeaders = []; + $tmp = ""; + foreach ($headersArray as $key) { + $lowerKey = StringUtil::toLower($key); + if (!StringUtil::contains($tmp, $lowerKey)) { + $tmp = "" . $tmp . "," . $lowerKey . ""; + $newHeaders[$lowerKey] = StringUtil::trim(@$headers[$key]); + } else { + $newHeaders[$lowerKey] = "" . @$newHeaders[$lowerKey] . "," . StringUtil::trim(@$headers[$key]) . ""; + } + } $canonicalizedHeaders = ""; $sortedHeaders = $this->getSignedHeaders($headers); foreach ($sortedHeaders as $header) { - $canonicalizedHeaders = "" . $canonicalizedHeaders . "" . $header . ":" . StringUtil::trim(@$headers[$header]) . "\n"; + $canonicalizedHeaders = "" . $canonicalizedHeaders . "" . $header . ":" . @$newHeaders[$header] . "\n"; } return $canonicalizedHeaders; } diff --git a/alibabacloud-gateway-pop/python/alibabacloud_gateway_pop/client.py b/alibabacloud-gateway-pop/python/alibabacloud_gateway_pop/client.py index bf9c4f9f..243ea990 100644 --- a/alibabacloud-gateway-pop/python/alibabacloud_gateway_pop/client.py +++ b/alibabacloud-gateway-pop/python/alibabacloud_gateway_pop/client.py @@ -11,6 +11,7 @@ from alibabacloud_tea_util.client import Client as UtilClient from alibabacloud_openapi_util.client import Client as OpenApiUtilClient from alibabacloud_darabonba_string.client import Client as StringClient +from alibabacloud_tea_xml.client import Client as XMLClient from alibabacloud_endpoint_util.client import Client as EndpointUtilClient from alibabacloud_darabonba_array.client import Client as ArrayClient from alibabacloud_darabonba_map.client import Client as MapClient @@ -229,8 +230,14 @@ def modify_response( request = context.request response = context.response if UtilClient.is_4xx(response.status_code) or UtilClient.is_5xx(response.status_code): - _res = UtilClient.read_as_json(response.body) - err = UtilClient.assert_as_map(_res) + err = {} + if not UtilClient.is_unset(response.headers.get('content-type')) and StringClient.contains(response.headers.get('content-type'), 'text/xml'): + _str = UtilClient.read_as_string(response.body) + resp_map = XMLClient.parse_xml(_str, None) + err = UtilClient.assert_as_map(resp_map.get('Error')) + else: + _res = UtilClient.read_as_json(response.body) + err = UtilClient.assert_as_map(_res) request_id = self.default_any(err.get('RequestId'), err.get('requestId')) if not UtilClient.is_unset(response.headers.get('x-acs-request-id')): request_id = response.headers.get('x-acs-request-id') @@ -270,8 +277,14 @@ async def modify_response_async( request = context.request response = context.response if UtilClient.is_4xx(response.status_code) or UtilClient.is_5xx(response.status_code): - _res = await UtilClient.read_as_json_async(response.body) - err = UtilClient.assert_as_map(_res) + err = {} + if not UtilClient.is_unset(response.headers.get('content-type')) and StringClient.contains(response.headers.get('content-type'), 'text/xml'): + _str = await UtilClient.read_as_string_async(response.body) + resp_map = XMLClient.parse_xml(_str, None) + err = UtilClient.assert_as_map(resp_map.get('Error')) + else: + _res = await UtilClient.read_as_json_async(response.body) + err = UtilClient.assert_as_map(_res) request_id = self.default_any(err.get('RequestId'), err.get('requestId')) if not UtilClient.is_unset(response.headers.get('x-acs-request-id')): request_id = response.headers.get('x-acs-request-id') @@ -445,10 +458,21 @@ def build_canonicalized_headers( self, headers: Dict[str, str], ) -> str: + # lower header key + headers_array = MapClient.key_set(headers) + new_headers = {} + tmp = '' + for key in headers_array: + lower_key = StringClient.to_lower(key) + if not StringClient.contains(tmp, lower_key): + tmp = f'{tmp},{lower_key}' + new_headers[lower_key] = StringClient.trim(headers.get(key)) + else: + new_headers[lower_key] = f'{new_headers.get(lower_key)},{StringClient.trim(headers.get(key))}' canonicalized_headers = '' sorted_headers = self.get_signed_headers(headers) for header in sorted_headers: - canonicalized_headers = f'{canonicalized_headers}{header}:{StringClient.trim(headers.get(header))}\n' + canonicalized_headers = f'{canonicalized_headers}{header}:{new_headers.get(header)}\n' return canonicalized_headers def get_signed_headers( diff --git a/alibabacloud-gateway-pop/python/setup.py b/alibabacloud-gateway-pop/python/setup.py index e462febc..acaba692 100644 --- a/alibabacloud-gateway-pop/python/setup.py +++ b/alibabacloud-gateway-pop/python/setup.py @@ -24,7 +24,7 @@ """ setup module for alibabacloud_gateway_pop. -Created on 23/07/2025 +Created on 15/08/2025 @author: Alibaba Cloud SDK """ @@ -38,7 +38,7 @@ VERSION = __import__(PACKAGE).__version__ REQUIRES = [ "alibabacloud_gateway_spi>=0.0.2, <1.0.0", - "alibabacloud_credentials>=0.3.6", + "alibabacloud_credentials>=1.0.2, <2.0.0", "alibabacloud_tea_util>=0.3.13, <1.0.0", "alibabacloud_openapi_util>=0.2.2, <1.0.0", "alibabacloud_endpoint_util>=0.0.4, <1.0.0", @@ -46,7 +46,8 @@ "alibabacloud_darabonba_signature_util>=0.0.4, <1.0.0", "alibabacloud_darabonba_string>=0.0.4, <1.0.0", "alibabacloud_darabonba_map>=0.0.1, <1.0.0", - "alibabacloud_darabonba_array>=0.1.0, <1.0.0" + "alibabacloud_darabonba_array>=0.1.0, <1.0.0", + "alibabacloud_tea_xml>=0.0.3, <1.0.0" ] LONG_DESCRIPTION = '' @@ -69,17 +70,19 @@ include_package_data=True, platforms="any", install_requires=REQUIRES, - python_requires=">=3.6", + python_requires=">=3.7", classifiers=( "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Programming Language :: Python", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.6", 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', "Topic :: Software Development" ) ) diff --git a/alibabacloud-gateway-pop/ts/package.json b/alibabacloud-gateway-pop/ts/package.json index 0f1fbde5..86d5b942 100644 --- a/alibabacloud-gateway-pop/ts/package.json +++ b/alibabacloud-gateway-pop/ts/package.json @@ -31,7 +31,8 @@ "@alicloud/darabonba-signature-util": "^0.0.4", "@alicloud/darabonba-string": "^1.0.2", "@alicloud/darabonba-map": "^0.0.1", - "@alicloud/darabonba-array": "^0.1.0" + "@alicloud/darabonba-array": "^0.1.0", + "@alicloud/tea-xml": "0.0.3" }, "files": [ "dist", diff --git a/alibabacloud-gateway-pop/ts/src/client.ts b/alibabacloud-gateway-pop/ts/src/client.ts index 40b5cc98..e5fce35a 100644 --- a/alibabacloud-gateway-pop/ts/src/client.ts +++ b/alibabacloud-gateway-pop/ts/src/client.ts @@ -9,6 +9,7 @@ import SignatureUtil from '@alicloud/darabonba-signature-util'; import String from '@alicloud/darabonba-string'; import Map from '@alicloud/darabonba-map'; import Array from '@alicloud/darabonba-array'; +import XML from '@alicloud/tea-xml'; import * as $tea from '@alicloud/tea-typescript'; @@ -146,8 +147,16 @@ export default class Client extends SPI { let request = context.request; let response = context.response; if (Util.is4xx(response.statusCode) || Util.is5xx(response.statusCode)) { - let _res = await Util.readAsJSON(response.body); - let err = Util.assertAsMap(_res); + let err : {[key: string ]: any} = { }; + if (!Util.isUnset(response.headers["content-type"]) && String.contains(response.headers["content-type"], "text/xml")) { + let _str = await Util.readAsString(response.body); + let respMap = XML.parseXml(_str, null); + err = Util.assertAsMap(respMap["Error"]); + } else { + let _res = await Util.readAsJSON(response.body); + err = Util.assertAsMap(_res); + } + let requestId = this.defaultAny(err["RequestId"], err["requestId"]); if (!Util.isUnset(response.headers["x-acs-request-id"])) { requestId = response.headers["x-acs-request-id"]; @@ -312,11 +321,26 @@ export default class Client extends SPI { } buildCanonicalizedHeaders(headers: {[key: string ]: string}): string { + // lower header key + let headersArray : string[] = Map.keySet(headers); + let newHeaders : {[key: string ]: string} = { }; + let tmp : string = ""; + + for (let key of headersArray) { + let lowerKey = String.toLower(key); + if (!String.contains(tmp, lowerKey)) { + tmp = `${tmp},${lowerKey}`; + newHeaders[lowerKey] = String.trim(headers[key]); + } else { + newHeaders[lowerKey] = `${newHeaders[lowerKey]},${String.trim(headers[key])}`; + } + + } let canonicalizedHeaders : string = ""; let sortedHeaders : string[] = this.getSignedHeaders(headers); for (let header of sortedHeaders) { - canonicalizedHeaders = `${canonicalizedHeaders}${header}:${String.trim(headers[header])}\n`; + canonicalizedHeaders = `${canonicalizedHeaders}${header}:${newHeaders[header]}\n`; } return canonicalizedHeaders; }