@@ -68,10 +68,11 @@ use url::ParseError as UrlError;
68
68
use header:: { Headers , Header , HeaderFormat } ;
69
69
use header:: { ContentLength , Host , Location } ;
70
70
use method:: Method ;
71
- use net:: { HttpConnector , NetworkConnector , NetworkStream , SslClient } ;
71
+ use net:: { NetworkConnector , NetworkStream , SslClient } ;
72
72
use Error ;
73
73
74
74
use self :: proxy:: { Proxy , tunnel} ;
75
+ use self :: scheme:: Scheme ;
75
76
pub use self :: pool:: Pool ;
76
77
pub use self :: request:: Request ;
77
78
pub use self :: response:: Response ;
@@ -84,10 +85,6 @@ pub mod response;
84
85
use http:: Protocol ;
85
86
use http:: h1:: Http11Protocol ;
86
87
87
- /// Proxy server configuration with a custom TLS wrapper.
88
- pub struct ProxyConfig < H , S > ( pub H , pub u16 , pub S )
89
- where H : Into < Cow < ' static , str > > ,
90
- S : SslClient < <HttpConnector as NetworkConnector >:: Stream > + Send + Sync + ' static ;
91
88
92
89
/// A Client to use additional features with Requests.
93
90
///
@@ -97,7 +94,7 @@ pub struct Client {
97
94
redirect_policy : RedirectPolicy ,
98
95
read_timeout : Option < Duration > ,
99
96
write_timeout : Option < Duration > ,
100
- proxy : Option < ( Cow < ' static , str > , u16 ) >
97
+ proxy : Option < ( Scheme , Cow < ' static , str > , u16 ) >
101
98
}
102
99
103
100
impl fmt:: Debug for Client {
@@ -123,27 +120,36 @@ impl Client {
123
120
Client :: with_connector ( Pool :: new ( config) )
124
121
}
125
122
123
+ /// Create a Client with an HTTP proxy to a (host, port).
126
124
pub fn with_http_proxy < H > ( host : H , port : u16 ) -> Client
127
125
where H : Into < Cow < ' static , str > > {
128
126
let host = host. into ( ) ;
129
- let proxy = tunnel ( ( host. clone ( ) , port) ) ;
127
+ let proxy = tunnel ( ( Scheme :: Http , host. clone ( ) , port) ) ;
130
128
let mut client = Client :: with_connector ( Pool :: with_connector ( Default :: default ( ) , proxy) ) ;
131
- client. proxy = Some ( ( host, port) ) ;
129
+ client. proxy = Some ( ( Scheme :: Http , host, port) ) ;
132
130
client
133
131
}
134
132
135
- pub fn with_proxy_config < H , S > ( proxy_config : ProxyConfig < H , S > ) -> Client
136
- where H : Into < Cow < ' static , str > > ,
137
- S : SslClient < <HttpConnector as NetworkConnector >:: Stream > + Send + Sync + ' static {
138
- let host = proxy_config. 0 . into ( ) ;
139
- let port = proxy_config. 1 ;
133
+ /// Create a Client using a proxy with a custom connector and SSL client.
134
+ pub fn with_proxy_config < C , S > ( proxy_config : ProxyConfig < C , S > ) -> Client
135
+ where C : NetworkConnector + Send + Sync + ' static ,
136
+ C :: Stream : NetworkStream + Send + Clone ,
137
+ S : SslClient < C :: Stream > + Send + Sync + ' static {
138
+
139
+ let scheme = proxy_config. scheme ;
140
+ let host = proxy_config. host ;
141
+ let port = proxy_config. port ;
140
142
let proxy = Proxy {
141
- connector : HttpConnector ,
142
- proxy : ( host . clone ( ) , port ) ,
143
- ssl : proxy_config. 2
143
+ proxy : ( scheme . clone ( ) , host . clone ( ) , port ) ,
144
+ connector : proxy_config . connector ,
145
+ ssl : proxy_config. ssl ,
144
146
} ;
145
- let mut client = Client :: with_connector ( Pool :: with_connector ( Default :: default ( ) , proxy) ) ;
146
- client. proxy = Some ( ( host, port) ) ;
147
+
148
+ let mut client = match proxy_config. pool_config {
149
+ Some ( pool_config) => Client :: with_connector ( Pool :: with_connector ( pool_config, proxy) ) ,
150
+ None => Client :: with_connector ( proxy) ,
151
+ } ;
152
+ client. proxy = Some ( ( scheme, host, port) ) ;
147
153
client
148
154
}
149
155
@@ -450,6 +456,47 @@ impl<'a> IntoUrl for &'a String {
450
456
}
451
457
}
452
458
459
+ /// Proxy server configuration with a custom connector and TLS wrapper.
460
+ pub struct ProxyConfig < C , S >
461
+ where C : NetworkConnector + Send + Sync + ' static ,
462
+ C :: Stream : NetworkStream + Clone + Send ,
463
+ S : SslClient < C :: Stream > + Send + Sync + ' static {
464
+ scheme : Scheme ,
465
+ host : Cow < ' static , str > ,
466
+ port : u16 ,
467
+ pool_config : Option < pool:: Config > ,
468
+ connector : C ,
469
+ ssl : S ,
470
+ }
471
+
472
+ impl < C , S > ProxyConfig < C , S >
473
+ where C : NetworkConnector + Send + Sync + ' static ,
474
+ C :: Stream : NetworkStream + Clone + Send ,
475
+ S : SslClient < C :: Stream > + Send + Sync + ' static {
476
+
477
+ /// Create a new `ProxyConfig`.
478
+ #[ inline]
479
+ pub fn new < H : Into < Cow < ' static , str > > > ( scheme : & str , host : H , port : u16 , connector : C , ssl : S ) -> ProxyConfig < C , S > {
480
+ ProxyConfig {
481
+ scheme : scheme. into ( ) ,
482
+ host : host. into ( ) ,
483
+ port : port,
484
+ pool_config : Some ( pool:: Config :: default ( ) ) ,
485
+ connector : connector,
486
+ ssl : ssl,
487
+ }
488
+ }
489
+
490
+ /// Change the `pool::Config` for the proxy.
491
+ ///
492
+ /// Passing `None` disables the `Pool`.
493
+ ///
494
+ /// The default is enabled, with the default `pool::Config`.
495
+ pub fn set_pool_config ( & mut self , pool_config : Option < pool:: Config > ) {
496
+ self . pool_config = pool_config;
497
+ }
498
+ }
499
+
453
500
/// Behavior regarding how to handle redirects within a Client.
454
501
#[ derive( Copy ) ]
455
502
pub enum RedirectPolicy {
@@ -499,13 +546,45 @@ fn get_host_and_port(url: &Url) -> ::Result<(&str, u16)> {
499
546
Ok ( ( host, port) )
500
547
}
501
548
549
+ mod scheme {
550
+
551
+ #[ derive( Clone , PartialEq , Eq , Debug , Hash ) ]
552
+ pub enum Scheme {
553
+ Http ,
554
+ Https ,
555
+ Other ( String )
556
+ }
557
+
558
+ impl < ' a > From < & ' a str > for Scheme {
559
+ fn from ( s : & ' a str ) -> Scheme {
560
+ match s {
561
+ "http" => Scheme :: Http ,
562
+ "https" => Scheme :: Https ,
563
+ s => Scheme :: Other ( String :: from ( s) )
564
+ }
565
+ }
566
+ }
567
+
568
+ impl AsRef < str > for Scheme {
569
+ fn as_ref ( & self ) -> & str {
570
+ match * self {
571
+ Scheme :: Http => "http" ,
572
+ Scheme :: Https => "https" ,
573
+ Scheme :: Other ( ref s) => s,
574
+ }
575
+ }
576
+ }
577
+
578
+ }
579
+
502
580
#[ cfg( test) ]
503
581
mod tests {
504
582
use std:: io:: Read ;
505
583
use header:: Server ;
506
584
use http:: h1:: Http11Message ;
507
585
use mock:: { MockStream , MockSsl } ;
508
586
use super :: { Client , RedirectPolicy } ;
587
+ use super :: scheme:: Scheme ;
509
588
use super :: proxy:: Proxy ;
510
589
use super :: pool:: Pool ;
511
590
use url:: Url ;
@@ -537,11 +616,11 @@ mod tests {
537
616
} ) ;
538
617
let tunnel = Proxy {
539
618
connector : ProxyConnector ,
540
- proxy : ( "example.proxy" . into ( ) , 8008 ) ,
619
+ proxy : ( Scheme :: Http , "example.proxy" . into ( ) , 8008 ) ,
541
620
ssl : MockSsl ,
542
621
} ;
543
622
let mut client = Client :: with_connector ( Pool :: with_connector ( Default :: default ( ) , tunnel) ) ;
544
- client. proxy = Some ( ( "example.proxy" . into ( ) , 8008 ) ) ;
623
+ client. proxy = Some ( ( Scheme :: Http , "example.proxy" . into ( ) , 8008 ) ) ;
545
624
let mut dump = vec ! [ ] ;
546
625
client. get ( "http://127.0.0.1/foo/bar" ) . send ( ) . unwrap ( ) . read_to_end ( & mut dump) . unwrap ( ) ;
547
626
@@ -566,11 +645,11 @@ mod tests {
566
645
} ) ;
567
646
let tunnel = Proxy {
568
647
connector : ProxyConnector ,
569
- proxy : ( "example.proxy" . into ( ) , 8008 ) ,
648
+ proxy : ( Scheme :: Http , "example.proxy" . into ( ) , 8008 ) ,
570
649
ssl : MockSsl ,
571
650
} ;
572
651
let mut client = Client :: with_connector ( Pool :: with_connector ( Default :: default ( ) , tunnel) ) ;
573
- client. proxy = Some ( ( "example.proxy" . into ( ) , 8008 ) ) ;
652
+ client. proxy = Some ( ( Scheme :: Http , "example.proxy" . into ( ) , 8008 ) ) ;
574
653
let mut dump = vec ! [ ] ;
575
654
client. get ( "https://127.0.0.1/foo/bar" ) . send ( ) . unwrap ( ) . read_to_end ( & mut dump) . unwrap ( ) ;
576
655
0 commit comments