1818 */
1919//! HTTP transport and connection components
2020
21+ #[ cfg( all( target_arch = "wasm32" , any( feature = "native-tls" , feature = "rustls-tls" ) ) ) ]
22+ compile_error ! ( "TLS features are not compatible with the wasm target" ) ;
23+
2124#[ cfg( any( feature = "native-tls" , feature = "rustls-tls" ) ) ]
2225use crate :: auth:: ClientCertificate ;
2326#[ cfg( any( feature = "native-tls" , feature = "rustls-tls" ) ) ]
@@ -130,6 +133,8 @@ fn build_meta() -> String {
130133 meta. push_str ( ",tls=n" ) ;
131134 } else if cfg ! ( feature = "rustls-tls" ) {
132135 meta. push_str ( ",tls=r" ) ;
136+ } else if cfg ! ( target_arch = "wasm32" ) {
137+ meta. push_str ( ",tls=w" ) ;
133138 }
134139
135140 meta
@@ -138,15 +143,19 @@ fn build_meta() -> String {
138143/// Builds a HTTP transport to make API calls to Elasticsearch
139144pub struct TransportBuilder {
140145 client_builder : reqwest:: ClientBuilder ,
141- conn_pool : Box < dyn ConnectionPool > ,
146+ conn_pool : Arc < dyn ConnectionPool > ,
142147 credentials : Option < Credentials > ,
143148 #[ cfg( any( feature = "native-tls" , feature = "rustls-tls" ) ) ]
144149 cert_validation : Option < CertificateValidation > ,
150+ #[ cfg( not( target_arch = "wasm32" ) ) ]
145151 proxy : Option < Url > ,
152+ #[ cfg( not( target_arch = "wasm32" ) ) ]
146153 proxy_credentials : Option < Credentials > ,
154+ #[ cfg( not( target_arch = "wasm32" ) ) ]
147155 disable_proxy : bool ,
148156 headers : HeaderMap ,
149157 meta_header : bool ,
158+ #[ cfg( not( target_arch = "wasm32" ) ) ]
150159 timeout : Option < Duration > ,
151160}
152161
@@ -159,15 +168,19 @@ impl TransportBuilder {
159168 {
160169 Self {
161170 client_builder : reqwest:: ClientBuilder :: new ( ) ,
162- conn_pool : Box :: new ( conn_pool) ,
171+ conn_pool : Arc :: new ( conn_pool) ,
163172 credentials : None ,
164173 #[ cfg( any( feature = "native-tls" , feature = "rustls-tls" ) ) ]
165174 cert_validation : None ,
175+ #[ cfg( not( target_arch = "wasm32" ) ) ]
166176 proxy : None ,
177+ #[ cfg( not( target_arch = "wasm32" ) ) ]
167178 proxy_credentials : None ,
179+ #[ cfg( not( target_arch = "wasm32" ) ) ]
168180 disable_proxy : false ,
169181 headers : HeaderMap :: new ( ) ,
170182 meta_header : true ,
183+ #[ cfg( not( target_arch = "wasm32" ) ) ]
171184 timeout : None ,
172185 }
173186 }
@@ -176,6 +189,7 @@ impl TransportBuilder {
176189 ///
177190 /// An optional username and password will be used to set the
178191 /// `Proxy-Authorization` header using Basic Authentication.
192+ #[ cfg( not( target_arch = "wasm32" ) ) ]
179193 pub fn proxy ( mut self , url : Url , username : Option < & str > , password : Option < & str > ) -> Self {
180194 self . proxy = Some ( url) ;
181195 if let Some ( u) = username {
@@ -189,6 +203,7 @@ impl TransportBuilder {
189203 /// Whether to disable proxies, including system proxies.
190204 ///
191205 /// NOTE: System proxies are enabled by default.
206+ #[ cfg( not( target_arch = "wasm32" ) ) ]
192207 pub fn disable_proxy ( mut self ) -> Self {
193208 self . disable_proxy = true ;
194209 self
@@ -241,6 +256,7 @@ impl TransportBuilder {
241256 ///
242257 /// The timeout is applied from when the request starts connecting until the response body has finished.
243258 /// Default is no timeout.
259+ #[ cfg( not( target_arch = "wasm32" ) ) ]
244260 pub fn timeout ( mut self , timeout : Duration ) -> Self {
245261 self . timeout = Some ( timeout) ;
246262 self
@@ -254,6 +270,7 @@ impl TransportBuilder {
254270 client_builder = client_builder. default_headers ( self . headers ) ;
255271 }
256272
273+ #[ cfg( not( target_arch = "wasm32" ) ) ]
257274 if let Some ( t) = self . timeout {
258275 client_builder = client_builder. timeout ( t) ;
259276 }
@@ -300,6 +317,7 @@ impl TransportBuilder {
300317 }
301318 }
302319
320+ #[ cfg( not( target_arch = "wasm32" ) ) ]
303321 if self . disable_proxy {
304322 client_builder = client_builder. no_proxy ( ) ;
305323 } else if let Some ( url) = self . proxy {
@@ -316,7 +334,7 @@ impl TransportBuilder {
316334 let client = client_builder. build ( ) ?;
317335 Ok ( Transport {
318336 client,
319- conn_pool : Arc :: new ( self . conn_pool ) ,
337+ conn_pool : self . conn_pool ,
320338 credentials : self . credentials ,
321339 send_meta : self . meta_header ,
322340 } )
@@ -363,7 +381,7 @@ impl Connection {
363381pub struct Transport {
364382 client : reqwest:: Client ,
365383 credentials : Option < Credentials > ,
366- conn_pool : Arc < Box < dyn ConnectionPool > > ,
384+ conn_pool : Arc < dyn ConnectionPool > ,
367385 send_meta : bool ,
368386}
369387
@@ -463,6 +481,7 @@ impl Transport {
463481 headers : HeaderMap ,
464482 query_string : Option < & Q > ,
465483 body : Option < B > ,
484+ #[ allow( unused_variables) ]
466485 timeout : Option < Duration > ,
467486 ) -> Result < reqwest:: RequestBuilder , Error >
468487 where
@@ -473,6 +492,7 @@ impl Transport {
473492 let url = connection. url . join ( path. trim_start_matches ( '/' ) ) ?;
474493 let mut request_builder = self . client . request ( reqwest_method, url) ;
475494
495+ #[ cfg( not( target_arch = "wasm32" ) ) ]
476496 if let Some ( t) = timeout {
477497 request_builder = request_builder. timeout ( t) ;
478498 }
@@ -564,6 +584,47 @@ impl Transport {
564584 ) ?)
565585 }
566586
587+ async fn reseed ( & self ) {
588+ // Requests will execute against old connection pool during reseed
589+ let connection = self . conn_pool . next ( ) ;
590+
591+ // Build node info request
592+ let node_request = self . request_builder (
593+ & connection,
594+ Method :: Get ,
595+ "_nodes/http?filter_path=nodes.*.http" ,
596+ HeaderMap :: default ( ) ,
597+ None :: < & ( ) > ,
598+ None :: < ( ) > ,
599+ None ,
600+ ) . unwrap ( ) ;
601+
602+ let scheme = connection. url . scheme ( ) ;
603+ let resp = node_request. send ( ) . await . unwrap ( ) ;
604+ let json: Value = resp. json ( ) . await . unwrap ( ) ;
605+ let connections: Vec < Connection > = json[ "nodes" ]
606+ . as_object ( )
607+ . unwrap ( )
608+ . iter ( )
609+ . map ( |( _, node) | {
610+ let address = node[ "http" ] [ "publish_address" ]
611+ . as_str ( )
612+ . or_else ( || {
613+ Some (
614+ node[ "http" ] [ "bound_address" ] . as_array ( ) . unwrap ( ) [ 0 ]
615+ . as_str ( )
616+ . unwrap ( ) ,
617+ )
618+ } )
619+ . unwrap ( ) ;
620+ let url = Self :: parse_to_url ( address, scheme) . unwrap ( ) ;
621+ Connection :: new ( url)
622+ } )
623+ . collect ( ) ;
624+
625+ self . conn_pool . reseed ( connections) ;
626+ }
627+
567628 /// Creates an asynchronous request that can be awaited
568629 pub async fn send < B , Q > (
569630 & self ,
@@ -578,47 +639,19 @@ impl Transport {
578639 B : Body ,
579640 Q : Serialize + ?Sized ,
580641 {
581- // Requests will execute against old connection pool during reseed
582642 if self . conn_pool . reseedable ( ) {
583- let conn_pool = self . conn_pool . clone ( ) ;
584- let connection = conn_pool. next ( ) ;
585-
586- // Build node info request
587- let node_request = self . request_builder (
588- & connection,
589- Method :: Get ,
590- "_nodes/http?filter_path=nodes.*.http" ,
591- headers. clone ( ) ,
592- None :: < & Q > ,
593- None :: < B > ,
594- timeout,
595- ) ?;
596-
597- tokio:: spawn ( async move {
598- let scheme = connection. url . scheme ( ) ;
599- let resp = node_request. send ( ) . await . unwrap ( ) ;
600- let json: Value = resp. json ( ) . await . unwrap ( ) ;
601- let connections: Vec < Connection > = json[ "nodes" ]
602- . as_object ( )
603- . unwrap ( )
604- . iter ( )
605- . map ( |( _, node) | {
606- let address = node[ "http" ] [ "publish_address" ]
607- . as_str ( )
608- . or_else ( || {
609- Some (
610- node[ "http" ] [ "bound_address" ] . as_array ( ) . unwrap ( ) [ 0 ]
611- . as_str ( )
612- . unwrap ( ) ,
613- )
614- } )
615- . unwrap ( ) ;
616- let url = Self :: parse_to_url ( address, scheme) . unwrap ( ) ;
617- Connection :: new ( url)
618- } )
619- . collect ( ) ;
620- conn_pool. reseed ( connections) ;
621- } ) ;
643+ #[ cfg( not( target_arch = "wasm32" ) ) ]
644+ {
645+ let transport = self . clone ( ) ;
646+ tokio:: spawn ( async move { transport. reseed ( ) . await } ) ;
647+ }
648+ #[ cfg( target_arch = "wasm32" ) ]
649+ {
650+ // Reseed synchronously (i.e. do not spawn a background task) in WASM.
651+ // Running in the background is platform-dependent (web-sys / wasi), we'll
652+ // address this if synchronous reseed is an issue.
653+ self . reseed ( ) . await
654+ }
622655 }
623656
624657 let connection = self . conn_pool . next ( ) ;
0 commit comments