@@ -13,6 +13,7 @@ use hyper::{header::CONTENT_TYPE, Method, Request, Response};
13
13
use hyper_rustls:: { HttpsConnector , HttpsConnectorBuilder } ;
14
14
use hyper_util:: client:: legacy:: { connect:: HttpConnector , Client } ;
15
15
use hyper_util:: rt:: TokioExecutor ;
16
+ use ic_transport_types:: { RejectResponse , TransportCallResponse } ;
16
17
use tower:: Service ;
17
18
18
19
use crate :: {
@@ -141,7 +142,7 @@ where
141
142
method : Method ,
142
143
url : String ,
143
144
body : Option < Vec < u8 > > ,
144
- ) -> Result < Vec < u8 > , AgentError > {
145
+ ) -> Result < ( StatusCode , Vec < u8 > ) , AgentError > {
145
146
let body = body. unwrap_or_default ( ) ;
146
147
fn map_error < E : Error + Send + Sync + ' static > ( err : E ) -> AgentError {
147
148
if any:: TypeId :: of :: < E > ( ) == any:: TypeId :: of :: < AgentError > ( ) {
@@ -207,7 +208,7 @@ where
207
208
content : body,
208
209
} ) )
209
210
} else {
210
- Ok ( body)
211
+ Ok ( ( status , body) )
211
212
}
212
213
}
213
214
}
@@ -217,13 +218,39 @@ where
217
218
B1 : HyperBody + From < Vec < u8 > > ,
218
219
S : HyperService < B1 > ,
219
220
{
220
- fn call ( & self , effective_canister_id : Principal , envelope : Vec < u8 > ) -> AgentFuture < Vec < u8 > > {
221
+ fn call (
222
+ & self ,
223
+ effective_canister_id : Principal ,
224
+ envelope : Vec < u8 > ,
225
+ ) -> AgentFuture < TransportCallResponse > {
221
226
Box :: pin ( async move {
222
- let url = format ! (
223
- "{}api/v3/canister/{effective_canister_id}/call" ,
224
- self . route_provider. route( ) ?
227
+ let api_version = if cfg ! ( feature = "sync_call" ) {
228
+ "v2"
229
+ } else {
230
+ "v3"
231
+ } ;
232
+
233
+ let endpoint = format ! (
234
+ "api/{}/canister/{}/call" ,
235
+ api_version,
236
+ effective_canister_id. to_text( )
225
237
) ;
226
- self . request ( Method :: POST , url, Some ( envelope) ) . await
238
+ let ( status_code, response_body) =
239
+ self . request ( Method :: POST , endpoint, Some ( envelope) ) . await ?;
240
+
241
+ if status_code == StatusCode :: ACCEPTED {
242
+ return Ok ( TransportCallResponse :: Accepted ) ;
243
+ }
244
+
245
+ // status_code == OK (200)
246
+ if cfg ! ( feature = "sync_call" ) {
247
+ serde_cbor:: from_slice ( & response_body) . map_err ( AgentError :: InvalidCborData )
248
+ } else {
249
+ let reject_response = serde_cbor:: from_slice :: < RejectResponse > ( & response_body)
250
+ . map_err ( AgentError :: InvalidCborData ) ?;
251
+
252
+ Err ( AgentError :: UncertifiedReject ( reject_response) )
253
+ }
227
254
} )
228
255
}
229
256
@@ -237,7 +264,9 @@ where
237
264
"{}api/v2/canister/{effective_canister_id}/read_state" ,
238
265
self . route_provider. route( ) ?
239
266
) ;
240
- self . request ( Method :: POST , url, Some ( envelope) ) . await
267
+ self . request ( Method :: POST , url, Some ( envelope) )
268
+ . await
269
+ . map ( |( _, body) | body)
241
270
} )
242
271
}
243
272
@@ -247,7 +276,9 @@ where
247
276
"{}api/v2/subnet/{subnet_id}/read_state" ,
248
277
self . route_provider. route( ) ?
249
278
) ;
250
- self . request ( Method :: POST , url, Some ( envelope) ) . await
279
+ self . request ( Method :: POST , url, Some ( envelope) )
280
+ . await
281
+ . map ( |( _, body) | body)
251
282
} )
252
283
}
253
284
@@ -257,14 +288,18 @@ where
257
288
"{}api/v2/canister/{effective_canister_id}/query" ,
258
289
self . route_provider. route( ) ?
259
290
) ;
260
- self . request ( Method :: POST , url, Some ( envelope) ) . await
291
+ self . request ( Method :: POST , url, Some ( envelope) )
292
+ . await
293
+ . map ( |( _, body) | body)
261
294
} )
262
295
}
263
296
264
297
fn status ( & self ) -> AgentFuture < Vec < u8 > > {
265
298
Box :: pin ( async move {
266
299
let url = format ! ( "{}api/v2/status" , self . route_provider. route( ) ?) ;
267
- self . request ( Method :: GET , url, None ) . await
300
+ self . request ( Method :: GET , url, None )
301
+ . await
302
+ . map ( |( _, body) | body)
268
303
} )
269
304
}
270
305
}
0 commit comments