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>(
183 self,
184 connector_layer: L,
185 ) -> EasyHttpConnectorBuilder<L::Service, ProxyTunnelStage<true>>
186 where
187 L: Layer<T>,
188 {
189 let connector = connector_layer.into_layer(self.connector);
190 EasyHttpConnectorBuilder {
191 connector,
192 _phantom: PhantomData,
193 }
194 }
195
196 #[cfg(feature = "boring")]
197 #[cfg_attr(docsrs, doc(cfg(feature = "boring")))]
198 pub fn with_tls_proxy_support_using_boringssl(
204 self,
205 ) -> EasyHttpConnectorBuilder<
206 boring_client::TlsConnector<T, boring_client::ConnectorKindTunnel>,
207 ProxyTunnelStage<true>,
208 > {
209 let connector = boring_client::TlsConnector::tunnel(self.connector, None);
210 EasyHttpConnectorBuilder {
211 connector,
212 _phantom: PhantomData,
213 }
214 }
215
216 #[cfg(feature = "boring")]
217 #[cfg_attr(docsrs, doc(cfg(feature = "boring")))]
218 pub fn with_tls_proxy_support_using_boringssl_config(
224 self,
225 config: TlsClientConfig,
226 ) -> EasyHttpConnectorBuilder<
227 boring_client::TlsConnector<T, boring_client::ConnectorKindTunnel>,
228 ProxyTunnelStage<true>,
229 > {
230 let connector =
231 boring_client::TlsConnector::tunnel(self.connector, None).with_base_config(config);
232 EasyHttpConnectorBuilder {
233 connector,
234 _phantom: PhantomData,
235 }
236 }
237
238 #[cfg(feature = "rustls")]
239 #[cfg_attr(docsrs, doc(cfg(feature = "rustls")))]
240 pub fn with_tls_proxy_support_using_rustls(
246 self,
247 ) -> EasyHttpConnectorBuilder<
248 rustls_client::TlsConnector<T, rustls_client::ConnectorKindTunnel>,
249 ProxyTunnelStage<true>,
250 > {
251 let connector = rustls_client::TlsConnector::tunnel(self.connector, None);
252
253 EasyHttpConnectorBuilder {
254 connector,
255 _phantom: PhantomData,
256 }
257 }
258
259 #[cfg(feature = "rustls")]
260 #[cfg_attr(docsrs, doc(cfg(feature = "rustls")))]
261 pub fn with_tls_proxy_support_using_rustls_config(
267 self,
268 config: TlsClientConfig,
269 ) -> EasyHttpConnectorBuilder<
270 rustls_client::TlsConnector<T, rustls_client::ConnectorKindTunnel>,
271 ProxyTunnelStage<true>,
272 > {
273 let connector =
274 rustls_client::TlsConnector::tunnel(self.connector, None).with_base_config(config);
275
276 EasyHttpConnectorBuilder {
277 connector,
278 _phantom: PhantomData,
279 }
280 }
281
282 pub fn without_tls_proxy_support(self) -> EasyHttpConnectorBuilder<T, ProxyTunnelStage<false>> {
288 EasyHttpConnectorBuilder {
289 connector: self.connector,
290 _phantom: PhantomData,
291 }
292 }
293}
294
295impl<T, const TLS_PROXY: bool> EasyHttpConnectorBuilder<T, ProxyTunnelStage<TLS_PROXY>> {
296 pub fn with_custom_proxy_connector<L>(
298 self,
299 connector_layer: L,
300 ) -> EasyHttpConnectorBuilder<L::Service, ProxyStage<true>>
301 where
302 L: Layer<T>,
303 {
304 let connector = connector_layer.into_layer(self.connector);
305 EasyHttpConnectorBuilder {
306 connector,
307 _phantom: PhantomData,
308 }
309 }
310
311 #[cfg(not(feature = "socks5"))]
312 pub fn with_proxy_support(
322 self,
323 ) -> EasyHttpConnectorBuilder<HttpProxyConnector<T>, ProxyStage<true>> {
324 self.with_http_proxy_support()
325 }
326
327 pub fn with_http_proxy_support(
335 self,
336 ) -> EasyHttpConnectorBuilder<HttpProxyConnector<T>, ProxyStage<true>> {
337 let connector =
338 HttpProxyConnector::optional(self.connector).with_tls_proxy_support(TLS_PROXY);
339
340 EasyHttpConnectorBuilder {
341 connector,
342 _phantom: PhantomData,
343 }
344 }
345
346 #[cfg(feature = "socks5")]
347 #[cfg_attr(docsrs, doc(cfg(feature = "socks5")))]
348 pub fn with_socks5_proxy_support(
352 self,
353 ) -> EasyHttpConnectorBuilder<Socks5ProxyConnector<T>, ProxyStage<true>> {
354 let connector = Socks5ProxyConnector::optional(self.connector);
355
356 EasyHttpConnectorBuilder {
357 connector,
358 _phantom: PhantomData,
359 }
360 }
361
362 pub fn without_proxy_support(self) -> EasyHttpConnectorBuilder<T, ProxyStage<false>> {
364 EasyHttpConnectorBuilder {
365 connector: self.connector,
366 _phantom: PhantomData,
367 }
368 }
369}
370
371impl<T: Clone, const TLS_PROXY: bool> EasyHttpConnectorBuilder<T, ProxyTunnelStage<TLS_PROXY>> {
372 #[cfg(feature = "socks5")]
373 #[cfg_attr(docsrs, doc(cfg(feature = "socks5")))]
374 pub fn with_proxy_support(
382 self,
383 ) -> EasyHttpConnectorBuilder<ProxyConnector<T>, ProxyStage<true>> {
384 use rama_http_backend::client::proxy::layer::HttpProxyConnectorLayer;
385 use rama_socks5::Socks5ProxyConnectorLayer;
386
387 let connector = ProxyConnector::optional(
388 self.connector,
389 Socks5ProxyConnectorLayer::required(),
390 HttpProxyConnectorLayer::required().with_tls_proxy_support(TLS_PROXY),
391 );
392
393 EasyHttpConnectorBuilder {
394 connector,
395 _phantom: PhantomData,
396 }
397 }
398}
399
400impl<T, const PROXY: bool> EasyHttpConnectorBuilder<T, ProxyStage<PROXY>> {
401 #[cfg(any(feature = "rustls", feature = "boring"))]
402 pub fn with_custom_tls_connector<L>(
408 self,
409 connector_layer: L,
410 ) -> EasyHttpConnectorBuilder<L::Service, TlsStage<PROXY>>
411 where
412 L: Layer<T>,
413 {
414 let connector = connector_layer.into_layer(self.connector);
415
416 EasyHttpConnectorBuilder {
417 connector,
418 _phantom: PhantomData,
419 }
420 }
421
422 #[cfg(feature = "boring")]
423 #[cfg_attr(docsrs, doc(cfg(feature = "boring")))]
424 pub fn with_tls_support_using_boringssl(
429 self,
430 config: TlsClientConfig,
431 ) -> EasyHttpConnectorBuilder<boring_client::TlsConnector<T>, TlsStage<PROXY>> {
432 let connector = boring_client::TlsConnector::auto(self.connector).with_base_config(config);
433
434 EasyHttpConnectorBuilder {
435 connector,
436 _phantom: PhantomData,
437 }
438 }
439
440 #[cfg(feature = "boring")]
441 #[cfg_attr(docsrs, doc(cfg(feature = "boring")))]
442 pub fn with_tls_support_using_boringssl_and_default_http_version(
452 self,
453 config: TlsClientConfig,
454 default_http_version: rama_http::Version,
455 ) -> EasyHttpConnectorBuilder<
456 AddInputExtension<boring_client::TlsConnector<T>, FallbackHttpVersion>,
457 TlsStage<PROXY>,
458 > {
459 let connector = boring_client::TlsConnector::auto(self.connector).with_base_config(config);
460 let connector =
461 AddInputExtension::new(connector, FallbackHttpVersion(default_http_version))
462 .with_overwrite(false);
463
464 EasyHttpConnectorBuilder {
465 connector,
466 _phantom: PhantomData,
467 }
468 }
469
470 #[cfg(feature = "rustls")]
471 #[cfg_attr(docsrs, doc(cfg(feature = "rustls")))]
472 pub fn with_tls_support_using_rustls(
477 self,
478 config: TlsClientConfig,
479 ) -> EasyHttpConnectorBuilder<rustls_client::TlsConnector<T>, TlsStage<PROXY>> {
480 let connector = rustls_client::TlsConnector::auto(self.connector).with_base_config(config);
481
482 EasyHttpConnectorBuilder {
483 connector,
484 _phantom: PhantomData,
485 }
486 }
487
488 #[cfg(feature = "rustls")]
489 #[cfg_attr(docsrs, doc(cfg(feature = "rustls")))]
490 pub fn with_tls_support_using_rustls_and_default_http_version(
500 self,
501 config: TlsClientConfig,
502 default_http_version: rama_http::Version,
503 ) -> EasyHttpConnectorBuilder<
504 AddInputExtension<rustls_client::TlsConnector<T>, FallbackHttpVersion>,
505 TlsStage<PROXY>,
506 > {
507 let connector = rustls_client::TlsConnector::auto(self.connector).with_base_config(config);
508 let connector =
509 AddInputExtension::new(connector, FallbackHttpVersion(default_http_version))
510 .with_overwrite(false);
511
512 EasyHttpConnectorBuilder {
513 connector,
514 _phantom: PhantomData,
515 }
516 }
517
518 pub fn without_tls_support(self) -> EasyHttpConnectorBuilder<T, TlsStage<PROXY>> {
520 EasyHttpConnectorBuilder {
521 connector: self.connector,
522 _phantom: PhantomData,
523 }
524 }
525}
526
527impl<T, const PROXY: bool> EasyHttpConnectorBuilder<T, TlsStage<PROXY>> {
528 pub fn with_default_http_connector<Body>(
530 self,
531 exec: Executor,
532 ) -> EasyHttpConnectorBuilder<HttpConnector<T, Body>, HttpStage<PROXY>> {
533 let connector = HttpConnector::new(self.connector, exec);
534
535 EasyHttpConnectorBuilder {
536 connector,
537 _phantom: PhantomData,
538 }
539 }
540
541 pub fn with_custom_http_connector<L>(
543 self,
544 connector_layer: L,
545 ) -> EasyHttpConnectorBuilder<L::Service, HttpStage<PROXY>>
546 where
547 L: Layer<T>,
548 {
549 let connector = connector_layer.into_layer(self.connector);
550
551 EasyHttpConnectorBuilder {
552 connector,
553 _phantom: PhantomData,
554 }
555 }
556}
557
558type DefaultHttpConnector<T> =
559 RequestVersionAdapter<HttpConnectRequestAdapter<ProxyRoutesConnector<T>>>;
560
561type ConfiguredConnectionBuilder<T> = EasyHttpConnectorBuilder<DefaultHttpConnector<T>, PoolStage>;
562
563type ConfiguredConnectionPoolBuilder<T> =
564 EasyHttpConnectorBuilder<DefaultHttpConnector<HttpPooledConnector<T>>, PoolStage>;
565
566type ErasedConnector<C> =
567 BoxService<ConnectRequest, EstablishedClientConnection<C, ConnectRequest>, ConnectionError>;
568
569type DefaultConnectionBuilder<C> =
570 ConfiguredConnectionBuilder<ProxyRouteFailureCacheConnector<ErasedConnector<C>>>;
571
572type DefaultConnectionPoolBuilder<C> =
573 ConfiguredConnectionPoolBuilder<ProxyRouteFailureCacheConnector<ErasedConnector<C>>>;
574
575struct ConnectorServiceAdapter<T>(T);
580
581impl<T> Service<ConnectRequest> for ConnectorServiceAdapter<T>
582where
583 T: ConnectorService<ConnectRequest>,
584{
585 type Output = EstablishedClientConnection<T::Connection, ConnectRequest>;
586 type Error = ConnectionError;
587
588 fn serve(
589 &self,
590 input: ConnectRequest,
591 ) -> impl Future<Output = Result<Self::Output, Self::Error>> + Send + '_ {
592 self.0.connect(input)
593 }
594}
595
596fn erase_connector<T>(connector: T) -> ErasedConnector<T::Connection>
597where
598 T: ConnectorService<ConnectRequest>,
599{
600 ConnectorServiceAdapter(connector).boxed()
601}
602
603fn finalize_http_connector<T>(connector: T) -> DefaultHttpConnector<T> {
604 let connector = ProxyRoutesConnector::new(connector);
605 let connector = HttpConnectRequestAdapter::new(connector);
606 RequestVersionAdapter::new(connector)
607}
608
609fn finish_without_connection_pool<T, Stage>(
610 builder: EasyHttpConnectorBuilder<T, Stage>,
611) -> ConfiguredConnectionBuilder<T>
612where
613 T: ConnectorService<ConnectRequest>,
614{
615 EasyHttpConnectorBuilder {
616 connector: finalize_http_connector(builder.connector),
617 _phantom: PhantomData,
618 }
619}
620
621fn finish_with_connection_pool<T, Stage>(
622 builder: EasyHttpConnectorBuilder<T, Stage>,
623 config: HttpPooledConnectorConfig,
624) -> Result<ConfiguredConnectionPoolBuilder<T>, BoxError>
625where
626 T: ConnectorService<ConnectRequest>,
627{
628 let connector = config.try_build_connector(builder.connector)?;
629 Ok(EasyHttpConnectorBuilder {
630 connector: finalize_http_connector(connector),
631 _phantom: PhantomData,
632 })
633}
634
635fn finish_with_default_connection_pool<T, Stage>(
636 builder: EasyHttpConnectorBuilder<T, Stage>,
637) -> ConfiguredConnectionPoolBuilder<T>
638where
639 T: ConnectorService<ConnectRequest>,
640{
641 let connector = HttpPooledConnectorConfig::build_default_connector(builder.connector);
642 EasyHttpConnectorBuilder {
643 connector: finalize_http_connector(connector),
644 _phantom: PhantomData,
645 }
646}
647
648fn finish_with_custom_connection_pool<T, Stage, P, R>(
649 builder: EasyHttpConnectorBuilder<T, Stage>,
650 pool: P,
651 req_to_conn_id: R,
652 wait_for_pool_timeout: Option<Duration>,
653) -> EasyHttpConnectorBuilder<PooledConnector<T, P, R>, PoolStage> {
654 let connector = PooledConnector::new(builder.connector, pool, req_to_conn_id)
655 .maybe_with_wait_for_pool_timeout(wait_for_pool_timeout);
656 EasyHttpConnectorBuilder {
657 connector,
658 _phantom: PhantomData,
659 }
660}
661
662impl<T, const PROXY: bool> EasyHttpConnectorBuilder<T, HttpStage<PROXY>> {
663 #[must_use]
669 pub fn with_proxy_route_failure_cache(
670 self,
671 cache: ProxyRouteFailureCache,
672 ) -> EasyHttpConnectorBuilder<
673 ProxyRouteFailureCacheConnector<ErasedConnector<T::Connection>>,
674 ProxyRouteFailureCacheStage,
675 >
676 where
677 T: ConnectorService<ConnectRequest>,
678 {
679 EasyHttpConnectorBuilder {
680 connector: ProxyRouteFailureCacheConnector::new(erase_connector(self.connector), cache),
681 _phantom: PhantomData,
682 }
683 }
684
685 #[must_use]
687 pub fn without_proxy_route_failure_cache(
688 self,
689 ) -> EasyHttpConnectorBuilder<T, ProxyRouteFailureCacheStage> {
690 EasyHttpConnectorBuilder {
691 connector: self.connector,
692 _phantom: PhantomData,
693 }
694 }
695}
696
697impl<T> EasyHttpConnectorBuilder<T, HttpStage<true>> {
698 pub fn without_connection_pool(self) -> DefaultConnectionBuilder<T::Connection>
704 where
705 T: ConnectorService<ConnectRequest>,
706 {
707 finish_without_connection_pool(
708 self.with_proxy_route_failure_cache(ProxyRouteFailureCache::default()),
709 )
710 }
711
712 pub fn try_with_connection_pool(
733 self,
734 config: HttpPooledConnectorConfig,
735 ) -> Result<DefaultConnectionPoolBuilder<T::Connection>, BoxError>
736 where
737 T: ConnectorService<ConnectRequest>,
738 {
739 finish_with_connection_pool(
740 self.with_proxy_route_failure_cache(ProxyRouteFailureCache::default()),
741 config,
742 )
743 }
744
745 pub fn with_default_connection_pool(self) -> DefaultConnectionPoolBuilder<T::Connection>
751 where
752 T: ConnectorService<ConnectRequest>,
753 {
754 finish_with_default_connection_pool(
755 self.with_proxy_route_failure_cache(ProxyRouteFailureCache::default()),
756 )
757 }
758
759 pub fn with_custom_connection_pool<P, R>(
780 self,
781 pool: P,
782 req_to_conn_id: R,
783 wait_for_pool_timeout: Option<Duration>,
784 ) -> EasyHttpConnectorBuilder<
785 PooledConnector<ProxyRouteFailureCacheConnector<ErasedConnector<T::Connection>>, P, R>,
786 PoolStage,
787 >
788 where
789 T: ConnectorService<ConnectRequest>,
790 {
791 finish_with_custom_connection_pool(
792 self.with_proxy_route_failure_cache(ProxyRouteFailureCache::default()),
793 pool,
794 req_to_conn_id,
795 wait_for_pool_timeout,
796 )
797 }
798}
799
800impl<T> EasyHttpConnectorBuilder<T, HttpStage<false>> {
801 pub fn without_connection_pool(self) -> ConfiguredConnectionBuilder<T>
807 where
808 T: ConnectorService<ConnectRequest>,
809 {
810 finish_without_connection_pool(self)
811 }
812
813 pub fn try_with_connection_pool(
815 self,
816 config: HttpPooledConnectorConfig,
817 ) -> Result<ConfiguredConnectionPoolBuilder<T>, BoxError>
818 where
819 T: ConnectorService<ConnectRequest>,
820 {
821 finish_with_connection_pool(self, config)
822 }
823
824 pub fn with_default_connection_pool(self) -> ConfiguredConnectionPoolBuilder<T>
827 where
828 T: ConnectorService<ConnectRequest>,
829 {
830 finish_with_default_connection_pool(self)
831 }
832
833 pub fn with_custom_connection_pool<P, R>(
835 self,
836 pool: P,
837 req_to_conn_id: R,
838 wait_for_pool_timeout: Option<Duration>,
839 ) -> EasyHttpConnectorBuilder<PooledConnector<T, P, R>, PoolStage> {
840 finish_with_custom_connection_pool(self, pool, req_to_conn_id, wait_for_pool_timeout)
841 }
842}
843
844impl<T> EasyHttpConnectorBuilder<T, ProxyRouteFailureCacheStage> {
845 pub fn without_connection_pool(self) -> ConfiguredConnectionBuilder<T>
847 where
848 T: ConnectorService<ConnectRequest>,
849 {
850 finish_without_connection_pool(self)
851 }
852
853 pub fn try_with_connection_pool(
855 self,
856 config: HttpPooledConnectorConfig,
857 ) -> Result<ConfiguredConnectionPoolBuilder<T>, BoxError>
858 where
859 T: ConnectorService<ConnectRequest>,
860 {
861 finish_with_connection_pool(self, config)
862 }
863
864 pub fn with_default_connection_pool(self) -> ConfiguredConnectionPoolBuilder<T>
867 where
868 T: ConnectorService<ConnectRequest>,
869 {
870 finish_with_default_connection_pool(self)
871 }
872
873 pub fn with_custom_connection_pool<P, R>(
881 self,
882 pool: P,
883 req_to_conn_id: R,
884 wait_for_pool_timeout: Option<Duration>,
885 ) -> EasyHttpConnectorBuilder<PooledConnector<T, P, R>, PoolStage> {
886 finish_with_custom_connection_pool(self, pool, req_to_conn_id, wait_for_pool_timeout)
887 }
888}
889
890impl<T> EasyHttpConnectorBuilder<T, PoolStage> {
891 pub fn build_client<Body, ModifiedBody, ConnResponse>(
893 self,
894 ) -> super::EasyHttpWebClient<Body, T::Output, ()>
895 where
896 Body: StreamingBody<Data: Send + 'static, Error: Into<BoxError>> + Unpin + Send + 'static,
897 ModifiedBody:
898 StreamingBody<Data: Send + 'static, Error: Into<BoxError>> + Unpin + Send + 'static,
899 T: Service<
900 Request<Body>,
901 Output = EstablishedClientConnection<ConnResponse, Request<ModifiedBody>>,
902 Error: Into<BoxError>,
903 >,
904 ConnResponse: ExtensionsRef,
905 {
906 super::EasyHttpWebClient::new(self.connector)
907 }
908}
909
910impl<T, S> EasyHttpConnectorBuilder<T, S> {
911 pub fn build_connector(self) -> T {
913 self.connector
914 }
915}