1#[cfg(any(feature = "rustls", feature = "boring"))]
2use rama_core::layer::AddInputExtension;
3use rama_core::rt::Executor;
4
5use super::{
6 HttpConnectRequestAdapter, HttpConnector, HttpPooledConnector, HttpPooledConnectorConfig,
7};
8#[cfg(any(feature = "rustls", feature = "boring"))]
9use crate::http::conn::FallbackHttpVersion;
10use crate::{
11 Layer, Service,
12 dns::client::{DnsConnectorLayer, resolver::DnsAddressResolver},
13 error::BoxError,
14 extensions::ExtensionsRef,
15 http::{
16 Request, StreamingBody, client::proxy::layer::HttpProxyConnector,
17 layer::version_adapter::RequestVersionAdapter,
18 },
19 net::client::{
20 ConnectRequest, ConnectionError, ConnectorService, EstablishedClientConnection,
21 ProxyRouteFailureCache, ProxyRouteFailureCacheConnector, ProxyRoutesConnector,
22 pool::PooledConnector,
23 },
24 service::BoxService,
25 tcp::client::service::TcpConnector,
26};
27use std::{marker::PhantomData, time::Duration};
28
29#[cfg(feature = "boring")]
30use crate::tls::boring::client as boring_client;
31
32#[cfg(any(feature = "rustls", feature = "boring"))]
33use crate::tls::client::TlsClientConfig;
34#[cfg(feature = "rustls")]
35use crate::tls::rustls::client as rustls_client;
36
37#[cfg(feature = "socks5")]
38use crate::{http::client::proxy_connector::ProxyConnector, proxy::socks5::Socks5ProxyConnector};
39
40#[derive(Default)]
42pub struct EasyHttpConnectorBuilder<C = (), S = ()> {
43 connector: C,
44 _phantom: PhantomData<S>,
45}
46
47#[non_exhaustive]
48#[derive(Debug)]
49pub struct TransportStage;
50#[non_exhaustive]
51#[derive(Debug)]
52pub struct DnsStage;
53#[non_exhaustive]
54#[derive(Debug)]
55pub struct ProxyTunnelStage<const TLS_PROXY: bool = true>;
56#[non_exhaustive]
57#[derive(Debug)]
58pub struct ProxyStage<const PROXY: bool = true>;
59#[non_exhaustive]
60#[derive(Debug)]
61pub struct TlsStage<const PROXY: bool = true>;
62#[non_exhaustive]
63#[derive(Debug)]
64pub struct HttpStage<const PROXY: bool = true>;
65#[non_exhaustive]
66#[derive(Debug)]
67pub struct ProxyRouteFailureCacheStage;
68#[non_exhaustive]
69#[derive(Debug)]
70pub struct PoolStage;
71
72impl EasyHttpConnectorBuilder {
73 #[must_use]
74 pub fn new() -> Self {
75 Self::default()
76 }
77
78 #[must_use]
79 pub fn with_default_transport_connector(
80 self,
81 ) -> EasyHttpConnectorBuilder<TcpConnector, TransportStage> {
82 let connector = TcpConnector::default();
83 EasyHttpConnectorBuilder {
84 connector,
85 _phantom: PhantomData,
86 }
87 }
88
89 pub fn with_custom_transport_connector<C>(
91 self,
92 connector: C,
93 ) -> EasyHttpConnectorBuilder<C, TransportStage> {
94 EasyHttpConnectorBuilder {
95 connector,
96 _phantom: PhantomData,
97 }
98 }
99}
100
101impl<T, Stage> EasyHttpConnectorBuilder<T, Stage> {
102 pub fn with_custom_connector<L>(
107 self,
108 connector_layer: L,
109 ) -> EasyHttpConnectorBuilder<L::Service, Stage>
110 where
111 L: Layer<T>,
112 {
113 self.map_connector(|c| connector_layer.into_layer(c))
114 }
115
116 pub fn map_connector<T2>(
121 self,
122 map_fn: impl FnOnce(T) -> T2,
123 ) -> EasyHttpConnectorBuilder<T2, Stage> {
124 let connector = map_fn(self.connector);
125 EasyHttpConnectorBuilder {
126 connector,
127 _phantom: PhantomData,
128 }
129 }
130}
131
132impl<T> EasyHttpConnectorBuilder<T, TransportStage> {
133 pub fn with_default_dns_connector(
135 self,
136 ) -> EasyHttpConnectorBuilder<crate::dns::client::DnsConnector<T>, DnsStage> {
137 self.with_dns_connector(DnsConnectorLayer::new())
138 }
139
140 pub fn with_dns_address_resolver<R: DnsAddressResolver + Clone>(
142 self,
143 resolver: R,
144 ) -> EasyHttpConnectorBuilder<crate::dns::client::DnsConnector<T, R>, DnsStage> {
145 self.with_dns_connector(DnsConnectorLayer::with_resolver(resolver))
146 }
147
148 pub fn without_dns_connector(
153 self,
154 ) -> EasyHttpConnectorBuilder<crate::dns::client::DnsConnector<T>, DnsStage> {
155 self.with_dns_connector(DnsConnectorLayer::new())
156 }
157
158 pub fn with_dns_connector<L>(
160 self,
161 connector_layer: L,
162 ) -> EasyHttpConnectorBuilder<L::Service, DnsStage>
163 where
164 L: Layer<T>,
165 {
166 let connector = connector_layer.into_layer(self.connector);
167 EasyHttpConnectorBuilder {
168 connector,
169 _phantom: PhantomData,
170 }
171 }
172}
173
174impl<T> EasyHttpConnectorBuilder<T, DnsStage> {
175 #[cfg(any(feature = "rustls", feature = "boring"))]
176 pub fn with_custom_tls_proxy_connector<L>(
178 self,
179 connector_layer: L,
180 ) -> EasyHttpConnectorBuilder<L::Service, ProxyTunnelStage<true>>
181 where
182 L: Layer<T>,
183 {
184 let connector = connector_layer.into_layer(self.connector);
185 EasyHttpConnectorBuilder {
186 connector,
187 _phantom: PhantomData,
188 }
189 }
190
191 #[cfg(feature = "boring")]
192 #[cfg_attr(docsrs, doc(cfg(feature = "boring")))]
193 pub fn with_tls_proxy_support_using_boringssl(
199 self,
200 ) -> EasyHttpConnectorBuilder<
201 boring_client::TlsConnector<T, boring_client::ConnectorKindTunnel>,
202 ProxyTunnelStage<true>,
203 > {
204 let connector = boring_client::TlsConnector::tunnel(self.connector, None);
205 EasyHttpConnectorBuilder {
206 connector,
207 _phantom: PhantomData,
208 }
209 }
210
211 #[cfg(feature = "boring")]
212 #[cfg_attr(docsrs, doc(cfg(feature = "boring")))]
213 pub fn with_tls_proxy_support_using_boringssl_config(
219 self,
220 config: TlsClientConfig,
221 ) -> EasyHttpConnectorBuilder<
222 boring_client::TlsConnector<T, boring_client::ConnectorKindTunnel>,
223 ProxyTunnelStage<true>,
224 > {
225 let connector =
226 boring_client::TlsConnector::tunnel(self.connector, None).with_base_config(config);
227 EasyHttpConnectorBuilder {
228 connector,
229 _phantom: PhantomData,
230 }
231 }
232
233 #[cfg(feature = "rustls")]
234 #[cfg_attr(docsrs, doc(cfg(feature = "rustls")))]
235 pub fn with_tls_proxy_support_using_rustls(
241 self,
242 ) -> EasyHttpConnectorBuilder<
243 rustls_client::TlsConnector<T, rustls_client::ConnectorKindTunnel>,
244 ProxyTunnelStage<true>,
245 > {
246 let connector = rustls_client::TlsConnector::tunnel(self.connector, None);
247
248 EasyHttpConnectorBuilder {
249 connector,
250 _phantom: PhantomData,
251 }
252 }
253
254 #[cfg(feature = "rustls")]
255 #[cfg_attr(docsrs, doc(cfg(feature = "rustls")))]
256 pub fn with_tls_proxy_support_using_rustls_config(
262 self,
263 config: TlsClientConfig,
264 ) -> EasyHttpConnectorBuilder<
265 rustls_client::TlsConnector<T, rustls_client::ConnectorKindTunnel>,
266 ProxyTunnelStage<true>,
267 > {
268 let connector =
269 rustls_client::TlsConnector::tunnel(self.connector, None).with_base_config(config);
270
271 EasyHttpConnectorBuilder {
272 connector,
273 _phantom: PhantomData,
274 }
275 }
276
277 pub fn without_tls_proxy_support(self) -> EasyHttpConnectorBuilder<T, ProxyTunnelStage<false>> {
283 EasyHttpConnectorBuilder {
284 connector: self.connector,
285 _phantom: PhantomData,
286 }
287 }
288}
289
290impl<T, const TLS_PROXY: bool> EasyHttpConnectorBuilder<T, ProxyTunnelStage<TLS_PROXY>> {
291 pub fn with_custom_proxy_connector<L>(
293 self,
294 connector_layer: L,
295 ) -> EasyHttpConnectorBuilder<L::Service, ProxyStage<true>>
296 where
297 L: Layer<T>,
298 {
299 let connector = connector_layer.into_layer(self.connector);
300 EasyHttpConnectorBuilder {
301 connector,
302 _phantom: PhantomData,
303 }
304 }
305
306 #[cfg(not(feature = "socks5"))]
307 pub fn with_proxy_support(
317 self,
318 ) -> EasyHttpConnectorBuilder<HttpProxyConnector<T>, ProxyStage<true>> {
319 self.with_http_proxy_support()
320 }
321
322 pub fn with_http_proxy_support(
330 self,
331 ) -> EasyHttpConnectorBuilder<HttpProxyConnector<T>, ProxyStage<true>> {
332 let connector =
333 HttpProxyConnector::optional(self.connector).with_tls_proxy_support(TLS_PROXY);
334
335 EasyHttpConnectorBuilder {
336 connector,
337 _phantom: PhantomData,
338 }
339 }
340
341 #[cfg(feature = "socks5")]
342 #[cfg_attr(docsrs, doc(cfg(feature = "socks5")))]
343 pub fn with_socks5_proxy_support(
347 self,
348 ) -> EasyHttpConnectorBuilder<Socks5ProxyConnector<T>, ProxyStage<true>> {
349 let connector = Socks5ProxyConnector::optional(self.connector);
350
351 EasyHttpConnectorBuilder {
352 connector,
353 _phantom: PhantomData,
354 }
355 }
356
357 pub fn without_proxy_support(self) -> EasyHttpConnectorBuilder<T, ProxyStage<false>> {
359 EasyHttpConnectorBuilder {
360 connector: self.connector,
361 _phantom: PhantomData,
362 }
363 }
364}
365
366impl<T: Clone, const TLS_PROXY: bool> EasyHttpConnectorBuilder<T, ProxyTunnelStage<TLS_PROXY>> {
367 #[cfg(feature = "socks5")]
368 #[cfg_attr(docsrs, doc(cfg(feature = "socks5")))]
369 pub fn with_proxy_support(
377 self,
378 ) -> EasyHttpConnectorBuilder<ProxyConnector<T>, ProxyStage<true>> {
379 use rama_http_backend::client::proxy::layer::HttpProxyConnectorLayer;
380 use rama_socks5::Socks5ProxyConnectorLayer;
381
382 let connector = ProxyConnector::optional(
383 self.connector,
384 Socks5ProxyConnectorLayer::required(),
385 HttpProxyConnectorLayer::required().with_tls_proxy_support(TLS_PROXY),
386 );
387
388 EasyHttpConnectorBuilder {
389 connector,
390 _phantom: PhantomData,
391 }
392 }
393}
394
395impl<T, const PROXY: bool> EasyHttpConnectorBuilder<T, ProxyStage<PROXY>> {
396 #[cfg(any(feature = "rustls", feature = "boring"))]
397 pub fn with_custom_tls_connector<L>(
403 self,
404 connector_layer: L,
405 ) -> EasyHttpConnectorBuilder<L::Service, TlsStage<PROXY>>
406 where
407 L: Layer<T>,
408 {
409 let connector = connector_layer.into_layer(self.connector);
410
411 EasyHttpConnectorBuilder {
412 connector,
413 _phantom: PhantomData,
414 }
415 }
416
417 #[cfg(feature = "boring")]
418 #[cfg_attr(docsrs, doc(cfg(feature = "boring")))]
419 pub fn with_tls_support_using_boringssl(
424 self,
425 config: TlsClientConfig,
426 ) -> EasyHttpConnectorBuilder<boring_client::TlsConnector<T>, TlsStage<PROXY>> {
427 let connector = boring_client::TlsConnector::auto(self.connector).with_base_config(config);
428
429 EasyHttpConnectorBuilder {
430 connector,
431 _phantom: PhantomData,
432 }
433 }
434
435 #[cfg(feature = "boring")]
436 #[cfg_attr(docsrs, doc(cfg(feature = "boring")))]
437 pub fn with_tls_support_using_boringssl_and_default_http_version(
447 self,
448 config: TlsClientConfig,
449 default_http_version: rama_http::Version,
450 ) -> EasyHttpConnectorBuilder<
451 AddInputExtension<boring_client::TlsConnector<T>, FallbackHttpVersion>,
452 TlsStage<PROXY>,
453 > {
454 let connector = boring_client::TlsConnector::auto(self.connector).with_base_config(config);
455 let connector =
456 AddInputExtension::new(connector, FallbackHttpVersion(default_http_version))
457 .with_overwrite(false);
458
459 EasyHttpConnectorBuilder {
460 connector,
461 _phantom: PhantomData,
462 }
463 }
464
465 #[cfg(feature = "rustls")]
466 #[cfg_attr(docsrs, doc(cfg(feature = "rustls")))]
467 pub fn with_tls_support_using_rustls(
472 self,
473 config: TlsClientConfig,
474 ) -> EasyHttpConnectorBuilder<rustls_client::TlsConnector<T>, TlsStage<PROXY>> {
475 let connector = rustls_client::TlsConnector::auto(self.connector).with_base_config(config);
476
477 EasyHttpConnectorBuilder {
478 connector,
479 _phantom: PhantomData,
480 }
481 }
482
483 #[cfg(feature = "rustls")]
484 #[cfg_attr(docsrs, doc(cfg(feature = "rustls")))]
485 pub fn with_tls_support_using_rustls_and_default_http_version(
495 self,
496 config: TlsClientConfig,
497 default_http_version: rama_http::Version,
498 ) -> EasyHttpConnectorBuilder<
499 AddInputExtension<rustls_client::TlsConnector<T>, FallbackHttpVersion>,
500 TlsStage<PROXY>,
501 > {
502 let connector = rustls_client::TlsConnector::auto(self.connector).with_base_config(config);
503 let connector =
504 AddInputExtension::new(connector, FallbackHttpVersion(default_http_version))
505 .with_overwrite(false);
506
507 EasyHttpConnectorBuilder {
508 connector,
509 _phantom: PhantomData,
510 }
511 }
512
513 pub fn without_tls_support(self) -> EasyHttpConnectorBuilder<T, TlsStage<PROXY>> {
515 EasyHttpConnectorBuilder {
516 connector: self.connector,
517 _phantom: PhantomData,
518 }
519 }
520}
521
522impl<T, const PROXY: bool> EasyHttpConnectorBuilder<T, TlsStage<PROXY>> {
523 pub fn with_default_http_connector<Body>(
525 self,
526 exec: Executor,
527 ) -> EasyHttpConnectorBuilder<HttpConnector<T, Body>, HttpStage<PROXY>> {
528 let connector = HttpConnector::new(self.connector, exec);
529
530 EasyHttpConnectorBuilder {
531 connector,
532 _phantom: PhantomData,
533 }
534 }
535
536 pub fn with_custom_http_connector<L>(
538 self,
539 connector_layer: L,
540 ) -> EasyHttpConnectorBuilder<L::Service, HttpStage<PROXY>>
541 where
542 L: Layer<T>,
543 {
544 let connector = connector_layer.into_layer(self.connector);
545
546 EasyHttpConnectorBuilder {
547 connector,
548 _phantom: PhantomData,
549 }
550 }
551}
552
553type DefaultHttpConnector<T> =
554 RequestVersionAdapter<HttpConnectRequestAdapter<ProxyRoutesConnector<T>>>;
555
556type ConfiguredConnectionBuilder<T> = EasyHttpConnectorBuilder<DefaultHttpConnector<T>, PoolStage>;
557
558type ConfiguredConnectionPoolBuilder<T> =
559 EasyHttpConnectorBuilder<DefaultHttpConnector<HttpPooledConnector<T>>, PoolStage>;
560
561type ErasedConnector<C> =
562 BoxService<ConnectRequest, EstablishedClientConnection<C, ConnectRequest>, ConnectionError>;
563
564type DefaultConnectionBuilder<C> =
565 ConfiguredConnectionBuilder<ProxyRouteFailureCacheConnector<ErasedConnector<C>>>;
566
567type DefaultConnectionPoolBuilder<C> =
568 ConfiguredConnectionPoolBuilder<ProxyRouteFailureCacheConnector<ErasedConnector<C>>>;
569
570struct ConnectorServiceAdapter<T>(T);
575
576impl<T> Service<ConnectRequest> for ConnectorServiceAdapter<T>
577where
578 T: ConnectorService<ConnectRequest>,
579{
580 type Output = EstablishedClientConnection<T::Connection, ConnectRequest>;
581 type Error = ConnectionError;
582
583 fn serve(
584 &self,
585 input: ConnectRequest,
586 ) -> impl Future<Output = Result<Self::Output, Self::Error>> + Send + '_ {
587 self.0.connect(input)
588 }
589}
590
591fn erase_connector<T>(connector: T) -> ErasedConnector<T::Connection>
592where
593 T: ConnectorService<ConnectRequest>,
594{
595 ConnectorServiceAdapter(connector).boxed()
596}
597
598fn finalize_http_connector<T>(connector: T) -> DefaultHttpConnector<T> {
599 let connector = ProxyRoutesConnector::new(connector);
600 let connector = HttpConnectRequestAdapter::new(connector);
601 RequestVersionAdapter::new(connector)
602}
603
604fn finish_without_connection_pool<T, Stage>(
605 builder: EasyHttpConnectorBuilder<T, Stage>,
606) -> ConfiguredConnectionBuilder<T>
607where
608 T: ConnectorService<ConnectRequest>,
609{
610 EasyHttpConnectorBuilder {
611 connector: finalize_http_connector(builder.connector),
612 _phantom: PhantomData,
613 }
614}
615
616fn finish_with_connection_pool<T, Stage>(
617 builder: EasyHttpConnectorBuilder<T, Stage>,
618 config: HttpPooledConnectorConfig,
619) -> Result<ConfiguredConnectionPoolBuilder<T>, BoxError>
620where
621 T: ConnectorService<ConnectRequest>,
622{
623 let connector = config.try_build_connector(builder.connector)?;
624 Ok(EasyHttpConnectorBuilder {
625 connector: finalize_http_connector(connector),
626 _phantom: PhantomData,
627 })
628}
629
630fn finish_with_default_connection_pool<T, Stage>(
631 builder: EasyHttpConnectorBuilder<T, Stage>,
632) -> ConfiguredConnectionPoolBuilder<T>
633where
634 T: ConnectorService<ConnectRequest>,
635{
636 let connector = HttpPooledConnectorConfig::build_default_connector(builder.connector);
637 EasyHttpConnectorBuilder {
638 connector: finalize_http_connector(connector),
639 _phantom: PhantomData,
640 }
641}
642
643fn finish_with_custom_connection_pool<T, Stage, P, R>(
644 builder: EasyHttpConnectorBuilder<T, Stage>,
645 pool: P,
646 req_to_conn_id: R,
647 wait_for_pool_timeout: Option<Duration>,
648) -> EasyHttpConnectorBuilder<PooledConnector<T, P, R>, PoolStage> {
649 let connector = PooledConnector::new(builder.connector, pool, req_to_conn_id)
650 .maybe_with_wait_for_pool_timeout(wait_for_pool_timeout);
651 EasyHttpConnectorBuilder {
652 connector,
653 _phantom: PhantomData,
654 }
655}
656
657impl<T, const PROXY: bool> EasyHttpConnectorBuilder<T, HttpStage<PROXY>> {
658 #[must_use]
664 pub fn with_proxy_route_failure_cache(
665 self,
666 cache: ProxyRouteFailureCache,
667 ) -> EasyHttpConnectorBuilder<
668 ProxyRouteFailureCacheConnector<ErasedConnector<T::Connection>>,
669 ProxyRouteFailureCacheStage,
670 >
671 where
672 T: ConnectorService<ConnectRequest>,
673 {
674 EasyHttpConnectorBuilder {
675 connector: ProxyRouteFailureCacheConnector::new(erase_connector(self.connector), cache),
676 _phantom: PhantomData,
677 }
678 }
679
680 #[must_use]
682 pub fn without_proxy_route_failure_cache(
683 self,
684 ) -> EasyHttpConnectorBuilder<T, ProxyRouteFailureCacheStage> {
685 EasyHttpConnectorBuilder {
686 connector: self.connector,
687 _phantom: PhantomData,
688 }
689 }
690}
691
692impl<T> EasyHttpConnectorBuilder<T, HttpStage<true>> {
693 pub fn without_connection_pool(self) -> DefaultConnectionBuilder<T::Connection>
699 where
700 T: ConnectorService<ConnectRequest>,
701 {
702 finish_without_connection_pool(
703 self.with_proxy_route_failure_cache(ProxyRouteFailureCache::default()),
704 )
705 }
706
707 pub fn try_with_connection_pool(
727 self,
728 config: HttpPooledConnectorConfig,
729 ) -> Result<DefaultConnectionPoolBuilder<T::Connection>, BoxError>
730 where
731 T: ConnectorService<ConnectRequest>,
732 {
733 finish_with_connection_pool(
734 self.with_proxy_route_failure_cache(ProxyRouteFailureCache::default()),
735 config,
736 )
737 }
738
739 pub fn with_default_connection_pool(self) -> DefaultConnectionPoolBuilder<T::Connection>
745 where
746 T: ConnectorService<ConnectRequest>,
747 {
748 finish_with_default_connection_pool(
749 self.with_proxy_route_failure_cache(ProxyRouteFailureCache::default()),
750 )
751 }
752
753 pub fn with_custom_connection_pool<P, R>(
768 self,
769 pool: P,
770 req_to_conn_id: R,
771 wait_for_pool_timeout: Option<Duration>,
772 ) -> EasyHttpConnectorBuilder<
773 PooledConnector<ProxyRouteFailureCacheConnector<ErasedConnector<T::Connection>>, P, R>,
774 PoolStage,
775 >
776 where
777 T: ConnectorService<ConnectRequest>,
778 {
779 finish_with_custom_connection_pool(
780 self.with_proxy_route_failure_cache(ProxyRouteFailureCache::default()),
781 pool,
782 req_to_conn_id,
783 wait_for_pool_timeout,
784 )
785 }
786}
787
788impl<T> EasyHttpConnectorBuilder<T, HttpStage<false>> {
789 pub fn without_connection_pool(self) -> ConfiguredConnectionBuilder<T>
795 where
796 T: ConnectorService<ConnectRequest>,
797 {
798 finish_without_connection_pool(self)
799 }
800
801 pub fn try_with_connection_pool(
803 self,
804 config: HttpPooledConnectorConfig,
805 ) -> Result<ConfiguredConnectionPoolBuilder<T>, BoxError>
806 where
807 T: ConnectorService<ConnectRequest>,
808 {
809 finish_with_connection_pool(self, config)
810 }
811
812 pub fn with_default_connection_pool(self) -> ConfiguredConnectionPoolBuilder<T>
815 where
816 T: ConnectorService<ConnectRequest>,
817 {
818 finish_with_default_connection_pool(self)
819 }
820
821 pub fn with_custom_connection_pool<P, R>(
823 self,
824 pool: P,
825 req_to_conn_id: R,
826 wait_for_pool_timeout: Option<Duration>,
827 ) -> EasyHttpConnectorBuilder<PooledConnector<T, P, R>, PoolStage> {
828 finish_with_custom_connection_pool(self, pool, req_to_conn_id, wait_for_pool_timeout)
829 }
830}
831
832impl<T> EasyHttpConnectorBuilder<T, ProxyRouteFailureCacheStage> {
833 pub fn without_connection_pool(self) -> ConfiguredConnectionBuilder<T>
835 where
836 T: ConnectorService<ConnectRequest>,
837 {
838 finish_without_connection_pool(self)
839 }
840
841 pub fn try_with_connection_pool(
843 self,
844 config: HttpPooledConnectorConfig,
845 ) -> Result<ConfiguredConnectionPoolBuilder<T>, BoxError>
846 where
847 T: ConnectorService<ConnectRequest>,
848 {
849 finish_with_connection_pool(self, config)
850 }
851
852 pub fn with_default_connection_pool(self) -> ConfiguredConnectionPoolBuilder<T>
855 where
856 T: ConnectorService<ConnectRequest>,
857 {
858 finish_with_default_connection_pool(self)
859 }
860
861 pub fn with_custom_connection_pool<P, R>(
863 self,
864 pool: P,
865 req_to_conn_id: R,
866 wait_for_pool_timeout: Option<Duration>,
867 ) -> EasyHttpConnectorBuilder<PooledConnector<T, P, R>, PoolStage> {
868 finish_with_custom_connection_pool(self, pool, req_to_conn_id, wait_for_pool_timeout)
869 }
870}
871
872impl<T> EasyHttpConnectorBuilder<T, PoolStage> {
873 pub fn build_client<Body, ModifiedBody, ConnResponse>(
875 self,
876 ) -> super::EasyHttpWebClient<Body, T::Output, ()>
877 where
878 Body: StreamingBody<Data: Send + 'static, Error: Into<BoxError>> + Unpin + Send + 'static,
879 ModifiedBody:
880 StreamingBody<Data: Send + 'static, Error: Into<BoxError>> + Unpin + Send + 'static,
881 T: Service<
882 Request<Body>,
883 Output = EstablishedClientConnection<ConnResponse, Request<ModifiedBody>>,
884 Error: Into<BoxError>,
885 >,
886 ConnResponse: ExtensionsRef,
887 {
888 super::EasyHttpWebClient::new(self.connector)
889 }
890}
891
892impl<T, S> EasyHttpConnectorBuilder<T, S> {
893 pub fn build_connector(self) -> T {
895 self.connector
896 }
897}