1
1
<?php
2
+
2
3
/*
3
4
* Licensed to the Apache Software Foundation (ASF) under one
4
5
* or more contributor license agreements. See the NOTICE file
17
18
* specific language governing permissions and limitations
18
19
* under the License.
19
20
*/
20
- class DefaultAcsClient implements IAcsClient
21
+
22
+ use GuzzleHttp \Client ;
23
+ use GuzzleHttp \Psr7 \Request as HttpRequest ;
24
+ use Psr \Http \Message \ResponseInterface ;
25
+
26
+ class DefaultAcsClient extends Client implements IAcsClient
21
27
{
28
+
22
29
public $ iClientProfile ;
23
- public $ __urlTestFlag__ ;
30
+
24
31
private $ locationService ;
25
-
26
- public function __construct ($ iClientProfile )
32
+
33
+ /**
34
+ * DefaultAcsClient constructor.
35
+ * @param array $iClientProfile
36
+ * @param array $config
37
+ */
38
+ public function __construct ($ iClientProfile , array $ config = [])
27
39
{
28
40
$ this ->iClientProfile = $ iClientProfile ;
29
- $ this ->__urlTestFlag__ = false ;
30
41
$ this ->locationService = new LocationService ($ this ->iClientProfile );
42
+
43
+ parent ::__construct (array_merge (['http_errors ' => false ], $ config ));
31
44
}
32
-
33
- public function getAcsResponse ($ request , $ iSigner = null , $ credential = null , $ autoRetry = true , $ maxRetryNumber = 3 )
45
+
46
+ public function getAcsResponse (AcsRequest $ request , $ iSigner = null , $ credential = null , $ autoRetry = true , $ maxRetryNumber = 3 )
34
47
{
35
48
$ httpResponse = $ this ->doActionImpl ($ request , $ iSigner , $ credential , $ autoRetry , $ maxRetryNumber );
36
- $ respObject = $ this -> parseAcsResponse ($ httpResponse-> getBody (), $ request -> getAcceptFormat () );
37
- if (false == $ httpResponse -> isSuccess ()) {
38
- $ this ->buildApiException ($ respObject , $ httpResponse ->getStatus ());
49
+ $ respObject = self :: parseAcsResponse ($ httpResponse );
50
+ if (false == self :: isSuccess ($ httpResponse )) {
51
+ $ this ->buildApiException ($ respObject , $ httpResponse ->getStatusCode ());
39
52
}
40
53
return $ respObject ;
41
54
}
42
55
56
+ public static function isSuccess (ResponseInterface $ response )
57
+ {
58
+ if (200 <= $ response ->getStatusCode () && 300 > $ response ->getStatusCode ()) {
59
+ return true ;
60
+ }
61
+ return false ;
62
+ }
63
+
43
64
private function doActionImpl ($ request , $ iSigner = null , $ credential = null , $ autoRetry = true , $ maxRetryNumber = 3 )
65
+ {
66
+ $ httpRequest = $ this ->buildHttpRequest ($ request , $ iSigner , $ credential );
67
+ $ httpResponse = $ this ->send ($ httpRequest );
68
+
69
+ $ retryTimes = 1 ;
70
+ while (500 <= $ httpResponse ->getStatusCode () && $ autoRetry && $ retryTimes < $ maxRetryNumber ) {
71
+ $ httpRequest = $ this ->buildHttpRequest ($ request , $ iSigner , $ credential );
72
+ $ httpResponse = $ this ->send ($ httpRequest );
73
+ $ retryTimes ++;
74
+ }
75
+ return $ httpResponse ;
76
+ }
77
+
78
+ public function doAction ($ request , $ iSigner = null , $ credential = null , $ autoRetry = true , $ maxRetryNumber = 3 )
79
+ {
80
+ trigger_error ("doAction() is deprecated. Please use getAcsResponse() instead. " , E_USER_NOTICE );
81
+ return $ this ->doActionImpl ($ request , $ iSigner , $ credential , $ autoRetry , $ maxRetryNumber );
82
+ }
83
+
84
+ private function prepareRequest ($ request )
85
+ {
86
+ if (null == $ request ->getRegionId ()) {
87
+ $ request ->setRegionId ($ this ->iClientProfile ->getRegionId ());
88
+ }
89
+ if (null == $ request ->getAcceptFormat ()) {
90
+ $ request ->setAcceptFormat ($ this ->iClientProfile ->getFormat ());
91
+ }
92
+ if (null == $ request ->getMethod ()) {
93
+ $ request ->setMethod ("GET " );
94
+ }
95
+ return $ request ;
96
+ }
97
+
98
+ public function buildHttpRequest (AcsRequest $ request , $ iSigner = null , $ credential = null )
44
99
{
45
100
if (null == $ this ->iClientProfile && (null == $ iSigner || null == $ credential
46
- || null == $ request ->getRegionId () || null == $ request ->getAcceptFormat ())) {
101
+ || null == $ request ->getRegionId () || null == $ request ->getAcceptFormat ())) {
47
102
throw new ClientException ("No active profile found. " , "SDK.InvalidProfile " );
48
103
}
49
104
if (null == $ iSigner ) {
@@ -56,79 +111,128 @@ private function doActionImpl($request, $iSigner = null, $credential = null, $au
56
111
57
112
// Get the domain from the Location Service by speicified `ServiceCode` and `RegionId`.
58
113
$ domain = null ;
59
- if (null != $ request ->getLocationServiceCode ())
60
- {
61
- $ domain = $ this ->locationService ->findProductDomain ($ request ->getRegionId (), $ request ->getLocationServiceCode (), $ request ->getLocationEndpointType (), $ request ->getProduct ());
62
- }
63
- if ($ domain == null )
64
- {
114
+ if (null != $ request ->getLocationServiceCode ()) {
115
+ $ domain = $ this ->locationService ->findProductDomain (
116
+ $ request ->getRegionId (),
117
+ $ request ->getLocationServiceCode (),
118
+ $ request ->getLocationEndpointType (),
119
+ $ request ->getProduct ()
120
+ );
121
+ }
122
+ if ($ domain == null ) {
65
123
$ domain = EndpointProvider::findProductDomain ($ request ->getRegionId (), $ request ->getProduct ());
66
124
}
67
125
68
126
if (null == $ domain ) {
69
127
throw new ClientException ("Can not find endpoint to access. " , "SDK.InvalidRegionId " );
70
128
}
71
- $ requestUrl = $ request ->composeUrl ($ iSigner , $ credential , $ domain );
72
129
73
- if ($ this ->__urlTestFlag__ ) {
74
- throw new ClientException ($ requestUrl , "URLTestFlagIsSet " );
75
- }
130
+ return (new HttpRequest (
131
+ $ request ->getMethod (),
132
+ $ request ->composeUrl ($ iSigner , $ credential , $ domain ),
133
+ $ request ->getHeaders (),
134
+ $ this ->getAcsRequestBody ($ request )
135
+ ))->withHeader ('Content-Type ' , 'application/x-www-form-urlencoded ' )
136
+ ->withHeader ('Accept ' , $ this ->convertStdHttpAccept ($ request ->getAcceptFormat ()));
137
+ }
76
138
77
- if (count ($ request ->getDomainParameter ())>0 ) {
78
- $ httpResponse = HttpHelper::curl ($ requestUrl , $ request ->getMethod (), $ request ->getDomainParameter (), $ request ->getHeaders ());
139
+ /**
140
+ * @param $format
141
+ * @return string
142
+ */
143
+ public function convertStdHttpAccept ($ format )
144
+ {
145
+ if ("JSON " == $ format ) {
146
+ return 'application/json ' ;
147
+ } elseif ("XML " == $ format ) {
148
+ return 'text/xml ' ;
149
+ } elseif ("RAW " == $ format ) {
150
+ return '*/* ' ;
79
151
} else {
80
- $ httpResponse = HttpHelper:: curl ( $ requestUrl , $ request -> getMethod (), $ request -> getContent (), $ request -> getHeaders ()) ;
152
+ return ' */* ' ;
81
153
}
82
-
83
- $ retryTimes = 1 ;
84
- while (500 <= $ httpResponse ->getStatus () && $ autoRetry && $ retryTimes < $ maxRetryNumber ) {
85
- $ requestUrl = $ request ->composeUrl ($ iSigner , $ credential , $ domain );
86
-
87
- if (count ($ request ->getDomainParameter ())>0 ) {
88
- $ httpResponse = HttpHelper::curl ($ requestUrl , $ request ->getMethod (), $ request ->getDomainParameter (), $ request ->getHeaders ());
89
- } else {
90
- $ httpResponse = HttpHelper::curl ($ requestUrl , $ request ->getMethod (), $ request ->getContent (), $ request ->getHeaders ());
91
- }
92
- $ retryTimes ++;
93
- }
94
- return $ httpResponse ;
95
154
}
96
-
97
- public function doAction ($ request , $ iSigner = null , $ credential = null , $ autoRetry = true , $ maxRetryNumber = 3 )
155
+
156
+ /**
157
+ * @param AcsRequest $request
158
+ * @return string
159
+ */
160
+ public function getAcsRequestBody (AcsRequest $ request )
98
161
{
99
- trigger_error ("doAction() is deprecated. Please use getAcsResponse() instead. " , E_USER_NOTICE );
100
- return $ this ->doActionImpl ($ request , $ iSigner , $ credential , $ autoRetry , $ maxRetryNumber );
162
+ if (method_exists ($ request , 'getDomainParameter ' ) && $ request ->getDomainParameter ()) {
163
+ return http_build_query ($ request ->getDomainParameter ());
164
+ }
165
+ return $ request ->getContent ();
101
166
}
102
-
103
- private function prepareRequest ($ request )
167
+
168
+ /**
169
+ * 同时发送多个请求
170
+ *
171
+ * @param array $requests
172
+ * @param callable|null $fulfilled
173
+ * @param callable|null $rejected
174
+ * @param int $concurrency
175
+ * @param array $args
176
+ * @return mixed
177
+ */
178
+ public function sendMultiRequests (
179
+ array $ requests ,
180
+ callable $ fulfilled = null ,
181
+ callable $ rejected = null ,
182
+ $ concurrency = 5 ,
183
+ array $ args = []
184
+ )
104
185
{
105
- if (null == $ request ->getRegionId ()) {
106
- $ request ->setRegionId ($ this ->iClientProfile ->getRegionId ());
107
- }
108
- if (null == $ request ->getAcceptFormat ()) {
109
- $ request ->setAcceptFormat ($ this ->iClientProfile ->getFormat ());
110
- }
111
- if (null == $ request ->getMethod ()) {
112
- $ request ->setMethod ("GET " );
113
- }
114
- return $ request ;
186
+ $ pool = new \GuzzleHttp \Pool ($ this , $ requests , [
187
+ 'fulfilled ' => function (ResponseInterface $ response , $ index ) use ($ fulfilled , $ requests , $ args ) {
188
+ $ respObject = self ::parseAcsResponse ($ response );
189
+ if (false == self ::isSuccess ($ response )) {
190
+ $ this ->buildApiException ($ respObject , $ response ->getStatusCode ());
191
+ }
192
+ $ fulfilled && call_user_func ($ fulfilled , $ respObject , $ response , $ index , $ args );
193
+ },
194
+ 'rejected ' => function ($ reason , $ index ) use ($ rejected , $ args ) {
195
+ $ rejected && call_user_func ($ rejected , $ reason , $ index , $ args );
196
+ },
197
+ 'concurrency ' => $ concurrency ,
198
+ ]);
199
+
200
+ return $ pool ->promise ()->wait ();
115
201
}
116
-
117
-
202
+
203
+ /**
204
+ * @param $respObject
205
+ * @param $httpStatus
206
+ * @throws Exception
207
+ * @throws ServerException|\Exception
208
+ */
118
209
private function buildApiException ($ respObject , $ httpStatus )
119
210
{
120
- throw new ServerException ($ respObject ->Message , $ respObject ->Code , $ httpStatus , $ respObject ->RequestId );
211
+ if (is_object ($ respObject ) && isset ($ respObject ->RequestId )) {
212
+ throw new ServerException ($ respObject ->Message , $ respObject ->Code , $ httpStatus , $ respObject ->RequestId );
213
+ } elseif (is_string ($ respObject )) {
214
+ throw new ServerException ($ respObject , -1 , $ httpStatus , 0 );
215
+ } else {
216
+ throw new Exception ("Invalid response object: " . gettype ($ respObject ));
217
+ }
121
218
}
122
-
123
- private function parseAcsResponse ($ body , $ format )
219
+
220
+ /**
221
+ * @param ResponseInterface $response
222
+ * @return mixed|SimpleXMLElement|string
223
+ */
224
+ public static function parseAcsResponse (ResponseInterface $ response )
124
225
{
125
- if ("JSON " == $ format ) {
126
- $ respObject = json_decode ($ body );
127
- } elseif ("XML " == $ format ) {
128
- $ respObject = @simplexml_load_string ($ body );
129
- } elseif ("RAW " == $ format ) {
130
- $ respObject = $ body ;
226
+ $ contentType = $ response ->getHeaderLine ('Content-Type ' );
227
+ $ body = $ response ->getBody ()->getContents ();
228
+
229
+ if (strpos ($ contentType , 'json ' ) !== false ) {
230
+ return json_decode ($ body );
231
+ } elseif (strpos ($ contentType , 'xml ' ) !== false ) {
232
+ return @simplexml_load_string ($ body );
233
+ } else {
234
+ return $ body ;
131
235
}
132
- return $ respObject ;
133
236
}
237
+
134
238
}
0 commit comments