@@ -184,38 +184,44 @@ impl NetworkState {
184184 Policy :: limited ( validated. limits . max_redirects as usize )
185185 } ;
186186
187- let http_client = Client :: builder ( )
188- . timeout ( Duration :: from_millis ( validated. limits . timeout_ms ) )
189- . redirect ( redirect_policy)
190- . build ( )
191- . map_err ( |err| NetworkStateError :: HttpClient ( err. to_string ( ) ) ) ?;
192-
193- let mut resolver_opts = ResolverOpts :: default ( ) ;
194- resolver_opts. timeout = Duration :: from_millis ( validated. limits . timeout_ms ) ;
195- resolver_opts. attempts = 1 ;
196- resolver_opts. cache_size = 0 ;
197- resolver_opts. use_hosts_file = false ;
198- resolver_opts. num_concurrent_reqs = 1 ;
199-
200- if validated. dns_policy . cache_ttl_secs > 0 {
201- let ttl = Duration :: from_secs ( validated. dns_policy . cache_ttl_secs ) ;
202- resolver_opts. positive_min_ttl = Some ( ttl) ;
203- resolver_opts. positive_max_ttl = Some ( ttl) ;
204- resolver_opts. negative_min_ttl = Some ( ttl) ;
205- resolver_opts. negative_max_ttl = Some ( ttl) ;
206- }
187+ // Create HTTP client and DNS resolver in a dedicated thread to avoid
188+ // "Cannot start a runtime from within a runtime" panic. Both
189+ // reqwest::blocking::Client and trust-dns Resolver internally call
190+ // block_on, which panics inside an existing tokio runtime.
191+ let timeout_ms = validated. limits . timeout_ms ;
192+ let dns_cache_ttl = validated. dns_policy . cache_ttl_secs ;
193+ let ( http_client, dns_resolver) = std:: thread:: spawn ( move || {
194+ let client = Client :: builder ( )
195+ . timeout ( Duration :: from_millis ( timeout_ms) )
196+ . redirect ( redirect_policy)
197+ . build ( )
198+ . map_err ( |err| NetworkStateError :: HttpClient ( err. to_string ( ) ) ) ?;
199+
200+ let mut resolver_opts = ResolverOpts :: default ( ) ;
201+ resolver_opts. timeout = Duration :: from_millis ( timeout_ms) ;
202+ resolver_opts. attempts = 1 ;
203+ resolver_opts. cache_size = 0 ;
204+ resolver_opts. use_hosts_file = false ;
205+ resolver_opts. num_concurrent_reqs = 1 ;
206+
207+ if dns_cache_ttl > 0 {
208+ let ttl = Duration :: from_secs ( dns_cache_ttl) ;
209+ resolver_opts. positive_min_ttl = Some ( ttl) ;
210+ resolver_opts. positive_max_ttl = Some ( ttl) ;
211+ resolver_opts. negative_min_ttl = Some ( ttl) ;
212+ resolver_opts. negative_max_ttl = Some ( ttl) ;
213+ }
207214
208- // Create DNS resolver in a dedicated thread to avoid
209- // "Cannot start a runtime from within a runtime" panic when
210- // trust-dns internally calls block_on during initialization.
211- let dns_resolver =
212- std:: thread:: spawn ( move || Resolver :: new ( ResolverConfig :: default ( ) , resolver_opts) )
213- . join ( )
214- . map_err ( |_| {
215- NetworkStateError :: DnsResolver ( "DNS resolver thread panicked" . to_string ( ) )
216- } ) ?
215+ let resolver = Resolver :: new ( ResolverConfig :: default ( ) , resolver_opts)
217216 . map_err ( |err| NetworkStateError :: DnsResolver ( err. to_string ( ) ) ) ?;
218217
218+ Ok :: < _ , NetworkStateError > ( ( client, resolver) )
219+ } )
220+ . join ( )
221+ . map_err ( |_| {
222+ NetworkStateError :: HttpClient ( "HTTP/DNS init thread panicked" . to_string ( ) )
223+ } ) ??;
224+
219225 Ok ( Self {
220226 policy : validated,
221227 audit_logger,
0 commit comments