11pub use super :: server:: { HttpResponse , WsMessageType } ;
2- use crate :: { get_blob, LazyLoadBlob as KiBlob , Message , Request as KiRequest } ;
2+ #[ cfg( not( feature = "hyperapp" ) ) ]
3+ use crate :: Message ;
4+ use crate :: { get_blob, LazyLoadBlob as KiBlob , Request as KiRequest } ;
35use http:: Method ;
46use serde:: { Deserialize , Serialize } ;
57use std:: collections:: HashMap ;
68use std:: str:: FromStr ;
79use thiserror:: Error ;
810
11+ #[ cfg( feature = "hyperapp" ) ]
12+ use crate :: hyperapp;
13+
914/// [`crate::Request`] type sent to the `http-client:distro:sys` service in order to open a
1015/// WebSocket connection, send a WebSocket message on an existing connection, or
1116/// send an HTTP request.
@@ -131,6 +136,7 @@ pub fn send_request(
131136/// Make an HTTP request using http-client and await its response.
132137///
133138/// Returns HTTP response from the `http` crate if successful, with the body type as bytes.
139+ #[ cfg( not( feature = "hyperapp" ) ) ]
134140pub fn send_request_await_response (
135141 method : Method ,
136142 url : url:: Url ,
@@ -190,6 +196,64 @@ pub fn send_request_await_response(
190196 . unwrap ( ) )
191197}
192198
199+ /// Make an HTTP request using http-client and await its response.
200+ ///
201+ /// Returns HTTP response from the `http` crate if successful, with the body type as bytes.
202+ #[ cfg( feature = "hyperapp" ) ]
203+ pub async fn send_request_await_response (
204+ method : Method ,
205+ url : url:: Url ,
206+ headers : Option < HashMap < String , String > > ,
207+ timeout : u64 ,
208+ body : Vec < u8 > ,
209+ ) -> std:: result:: Result < http:: Response < Vec < u8 > > , HttpClientError > {
210+ let request = KiRequest :: to ( ( "our" , "http-client" , "distro" , "sys" ) )
211+ . body (
212+ serde_json:: to_vec ( & HttpClientAction :: Http ( OutgoingHttpRequest {
213+ method : method. to_string ( ) ,
214+ version : None ,
215+ url : url. to_string ( ) ,
216+ headers : headers. unwrap_or_default ( ) ,
217+ } ) )
218+ . map_err ( |_| HttpClientError :: MalformedRequest ) ?,
219+ )
220+ . blob_bytes ( body)
221+ . expects_response ( timeout) ;
222+
223+ let resp_result =
224+ hyperapp:: send :: < std:: result:: Result < HttpClientResponse , HttpClientError > > ( request)
225+ . await
226+ . map_err ( |_| {
227+ HttpClientError :: ExecuteRequestFailed ( "http-client timed out" . to_string ( ) )
228+ } ) ?;
229+
230+ let resp = match resp_result {
231+ Ok ( HttpClientResponse :: Http ( resp) ) => resp,
232+ Ok ( HttpClientResponse :: WebSocketAck ) => {
233+ return Err ( HttpClientError :: ExecuteRequestFailed (
234+ "http-client gave unexpected response" . to_string ( ) ,
235+ ) )
236+ }
237+ Err ( e) => return Err ( e) ,
238+ } ;
239+ let mut http_response = http:: Response :: builder ( )
240+ . status ( http:: StatusCode :: from_u16 ( resp. status ) . unwrap_or_default ( ) ) ;
241+ let headers = http_response. headers_mut ( ) . unwrap ( ) ;
242+ for ( key, value) in & resp. headers {
243+ let Ok ( key) = http:: header:: HeaderName :: from_str ( key) else {
244+ continue ;
245+ } ;
246+ let Ok ( value) = http:: header:: HeaderValue :: from_str ( value) else {
247+ continue ;
248+ } ;
249+ headers. insert ( key, value) ;
250+ }
251+ Ok ( http_response
252+ . body ( get_blob ( ) . unwrap_or_default ( ) . bytes )
253+ . unwrap ( ) )
254+ }
255+
256+ #[ cfg( not( feature = "hyperapp" ) ) ]
193257pub fn open_ws_connection (
194258 url : String ,
195259 headers : Option < HashMap < String , String > > ,
@@ -231,7 +295,37 @@ pub fn send_ws_client_push(channel_id: u32, message_type: WsMessageType, blob: K
231295 . unwrap ( )
232296}
233297
298+ #[ cfg( feature = "hyperapp" ) ]
299+ pub async fn open_ws_connection (
300+ url : String ,
301+ headers : Option < HashMap < String , String > > ,
302+ channel_id : u32 ,
303+ ) -> std:: result:: Result < ( ) , HttpClientError > {
304+ let request = KiRequest :: to ( ( "our" , "http-client" , "distro" , "sys" ) )
305+ . body (
306+ serde_json:: to_vec ( & HttpClientAction :: WebSocketOpen {
307+ url : url. clone ( ) ,
308+ headers : headers. unwrap_or ( HashMap :: new ( ) ) ,
309+ channel_id,
310+ } )
311+ . unwrap ( ) ,
312+ )
313+ . expects_response ( 5 ) ;
314+
315+ let resp_result =
316+ hyperapp:: send :: < std:: result:: Result < HttpClientResponse , HttpClientError > > ( request)
317+ . await
318+ . map_err ( |_| HttpClientError :: WsOpenFailed { url : url. clone ( ) } ) ?;
319+
320+ match resp_result {
321+ Ok ( HttpClientResponse :: WebSocketAck ) => Ok ( ( ) ) ,
322+ Err ( e) => Err ( e) ,
323+ _ => Err ( HttpClientError :: WsOpenFailed { url } ) ,
324+ }
325+ }
326+
234327/// Close a WebSocket connection.
328+ #[ cfg( not( feature = "hyperapp" ) ) ]
235329pub fn close_ws_connection ( channel_id : u32 ) -> std:: result:: Result < ( ) , HttpClientError > {
236330 let Ok ( Ok ( Message :: Response { body, .. } ) ) =
237331 KiRequest :: to ( ( "our" , "http-client" , "distro" , "sys" ) )
@@ -251,3 +345,27 @@ pub fn close_ws_connection(channel_id: u32) -> std::result::Result<(), HttpClien
251345 _ => Err ( HttpClientError :: WsCloseFailed { channel_id } ) ,
252346 }
253347}
348+
349+ /// Close a WebSocket connection.
350+ #[ cfg( feature = "hyperapp" ) ]
351+ pub async fn close_ws_connection ( channel_id : u32 ) -> std:: result:: Result < ( ) , HttpClientError > {
352+ let request = KiRequest :: to ( ( "our" , "http-client" , "distro" , "sys" ) )
353+ . body (
354+ serde_json:: json!( HttpClientAction :: WebSocketClose { channel_id } )
355+ . to_string ( )
356+ . as_bytes ( )
357+ . to_vec ( ) ,
358+ )
359+ . expects_response ( 5 ) ;
360+
361+ let resp_result =
362+ hyperapp:: send :: < std:: result:: Result < HttpClientResponse , HttpClientError > > ( request)
363+ . await
364+ . map_err ( |_| HttpClientError :: WsCloseFailed { channel_id } ) ?;
365+
366+ match resp_result {
367+ Ok ( HttpClientResponse :: WebSocketAck ) => Ok ( ( ) ) ,
368+ Err ( e) => Err ( e) ,
369+ _ => Err ( HttpClientError :: WsCloseFailed { channel_id } ) ,
370+ }
371+ }
0 commit comments