@@ -5,19 +5,25 @@ use crate::bstr::BStr;
5
5
impl crate :: Repository {
6
6
/// Produce configuration suitable for `url`, as differentiated by its protocol/scheme, to be passed to a transport instance via
7
7
/// [configure()][git_transport::client::TransportWithoutIO::configure()] (via `&**config` to pass the contained `Any` and not the `Box`).
8
- /// `None` is returned if there is no known configuration.
8
+ /// `None` is returned if there is no known configuration. If `remote_name` is not `None`, the remote's name may contribute to
9
+ /// configuration overrides, typically for the HTTP transport.
9
10
///
10
11
/// Note that the caller may cast the instance themselves to modify it before passing it on.
11
12
///
12
- ///
13
- // let (mut cascade, _action_with_normalized_url, prompt_opts) =
14
- // self.remote.repo.config_snapshot().credential_helpers(url)?;
15
- // Ok(Box::new(move |action| cascade.invoke(action, prompt_opts.clone())) as AuthenticateFn<'_>)
16
- /// For transports that support proxy authentication, the authentication
17
- /// [default authentication method](crate::config::Snapshot::credential_helpers()) will be used with the url of the proxy.
13
+ /// For transports that support proxy authentication, the
14
+ /// [default authentication method](crate::config::Snapshot::credential_helpers()) will be used with the url of the proxy
15
+ /// if it contains a user name.
16
+ #[ cfg_attr(
17
+ not( any(
18
+ feature = "blocking-http-transport-reqwest" ,
19
+ feature = "blocking-http-transport-curl"
20
+ ) ) ,
21
+ allow( unused_variables)
22
+ ) ]
18
23
pub fn transport_options < ' a > (
19
24
& self ,
20
25
url : impl Into < & ' a BStr > ,
26
+ remote_name : Option < & BStr > ,
21
27
) -> Result < Option < Box < dyn Any > > , crate :: config:: transport:: Error > {
22
28
let url = git_url:: parse ( url. into ( ) ) ?;
23
29
use git_url:: Scheme :: * ;
@@ -49,12 +55,15 @@ impl crate::Repository {
49
55
fn try_cow_to_string (
50
56
v : Cow < ' _ , BStr > ,
51
57
lenient : bool ,
52
- key : & ' static str ,
58
+ key : impl Into < Cow < ' static , BStr > > ,
53
59
) -> Result < Option < String > , crate :: config:: transport:: Error > {
54
60
Vec :: from ( v. into_owned ( ) )
55
61
. into_string ( )
56
62
. map ( Some )
57
- . map_err ( |err| crate :: config:: transport:: Error :: IllformedUtf8 { source : err, key } )
63
+ . map_err ( |err| crate :: config:: transport:: Error :: IllformedUtf8 {
64
+ source : err,
65
+ key : key. into ( ) ,
66
+ } )
58
67
. with_leniency ( lenient)
59
68
}
60
69
@@ -71,6 +80,7 @@ impl crate::Repository {
71
80
{
72
81
Ok ( integer_opt ( config, lenient, key, kind, filter) ?. unwrap_or ( default) )
73
82
}
83
+
74
84
fn integer_opt < T > (
75
85
config : & git_config:: File < ' static > ,
76
86
lenient : bool ,
@@ -103,6 +113,55 @@ impl crate::Repository {
103
113
. transpose ( )
104
114
. with_leniency ( lenient)
105
115
}
116
+
117
+ fn proxy_auth_method (
118
+ value_and_key : Option < ( Cow < ' _ , BStr > , Cow < ' static , BStr > ) > ,
119
+ lenient : bool ,
120
+ ) -> Result < ProxyAuthMethod , crate :: config:: transport:: Error > {
121
+ let value = value_and_key
122
+ . and_then ( |( v, k) | {
123
+ try_cow_to_string ( v, lenient, k. clone ( ) )
124
+ . map ( |v| v. map ( |v| ( v, k) ) )
125
+ . transpose ( )
126
+ } )
127
+ . transpose ( ) ?
128
+ . map ( |( method, key) | {
129
+ Ok ( match method. as_str ( ) {
130
+ "anyauth" => ProxyAuthMethod :: AnyAuth ,
131
+ "basic" => ProxyAuthMethod :: Basic ,
132
+ "digest" => ProxyAuthMethod :: Digest ,
133
+ "negotiate" => ProxyAuthMethod :: Negotiate ,
134
+ "ntlm" => ProxyAuthMethod :: Ntlm ,
135
+ _ => {
136
+ return Err ( crate :: config:: transport:: http:: Error :: InvalidProxyAuthMethod {
137
+ value : method,
138
+ key,
139
+ } )
140
+ }
141
+ } )
142
+ } )
143
+ . transpose ( ) ?
144
+ . unwrap_or_default ( ) ;
145
+ Ok ( value)
146
+ }
147
+
148
+ fn proxy (
149
+ value : Option < ( Cow < ' _ , BStr > , Cow < ' static , BStr > ) > ,
150
+ lenient : bool ,
151
+ ) -> Result < Option < String > , crate :: config:: transport:: Error > {
152
+ Ok ( value
153
+ . and_then ( |( v, k) | try_cow_to_string ( v, lenient, k. clone ( ) ) . transpose ( ) )
154
+ . transpose ( ) ?
155
+ . map ( |mut proxy| {
156
+ if !proxy. trim ( ) . is_empty ( ) && !proxy. contains ( "://" ) {
157
+ proxy. insert_str ( 0 , "http://" ) ;
158
+ proxy
159
+ } else {
160
+ proxy
161
+ }
162
+ } ) )
163
+ }
164
+
106
165
let mut opts = http:: Options :: default ( ) ;
107
166
let config = & self . config . resolved ;
108
167
let mut trusted_only = self . filter_config_section ( ) ;
@@ -113,7 +172,7 @@ impl crate::Repository {
113
172
. strings_filter ( "http" , None , "extraHeader" , & mut trusted_only)
114
173
. unwrap_or_default ( )
115
174
. into_iter ( )
116
- . map ( |v| try_cow_to_string ( v, lenient, "http.extraHeader" ) )
175
+ . map ( |v| try_cow_to_string ( v, lenient, Cow :: Borrowed ( "http.extraHeader" . into ( ) ) ) )
117
176
{
118
177
let header = header?;
119
178
if let Some ( header) = header {
@@ -149,38 +208,34 @@ impl crate::Repository {
149
208
integer ( config, lenient, "http.lowSpeedTime" , "u64" , trusted_only, 0 ) ?;
150
209
opts. low_speed_limit_bytes_per_second =
151
210
integer ( config, lenient, "http.lowSpeedLimit" , "u32" , trusted_only, 0 ) ?;
152
- opts. proxy = config
153
- . string_filter ( "http" , None , "proxy" , & mut trusted_only)
154
- . and_then ( |v| try_cow_to_string ( v, lenient, "http.proxy" ) . transpose ( ) )
155
- . transpose ( ) ?
156
- . map ( |mut proxy| {
157
- if !proxy. trim ( ) . is_empty ( ) && !proxy. contains ( "://" ) {
158
- proxy. insert_str ( 0 , "http://" ) ;
159
- proxy
160
- } else {
161
- proxy
162
- }
163
- } ) ;
164
- opts. proxy_auth_method = config
165
- . string_filter ( "http" , None , "proxyAuthMethod" , & mut trusted_only)
166
- . and_then ( |v| try_cow_to_string ( v, lenient, "http.proxyAuthMethod" ) . transpose ( ) )
167
- . transpose ( ) ?
168
- . map ( |method| {
169
- Ok ( match method. as_str ( ) {
170
- "anyauth" => ProxyAuthMethod :: AnyAuth ,
171
- "basic" => ProxyAuthMethod :: Basic ,
172
- "digest" => ProxyAuthMethod :: Digest ,
173
- "negotiate" => ProxyAuthMethod :: Negotiate ,
174
- "ntlm" => ProxyAuthMethod :: Ntlm ,
175
- _ => {
176
- return Err ( crate :: config:: transport:: http:: Error :: InvalidProxyAuthMethod {
177
- value : method,
178
- } )
179
- }
211
+ opts. proxy = proxy (
212
+ remote_name
213
+ . and_then ( |name| {
214
+ config
215
+ . string_filter ( "remote" , Some ( name) , "proxy" , & mut trusted_only)
216
+ . map ( |v| ( v, Cow :: Owned ( format ! ( "remote.{name}.proxy" ) . into ( ) ) ) )
180
217
} )
181
- } )
182
- . transpose ( ) ?
183
- . unwrap_or_default ( ) ;
218
+ . or_else ( || {
219
+ config
220
+ . string_filter ( "http" , None , "proxy" , & mut trusted_only)
221
+ . map ( |v| ( v, Cow :: Borrowed ( "http.proxy" . into ( ) ) ) )
222
+ } ) ,
223
+ lenient,
224
+ ) ?;
225
+ opts. proxy_auth_method = proxy_auth_method (
226
+ remote_name
227
+ . and_then ( |name| {
228
+ config
229
+ . string_filter ( "remote" , Some ( name) , "proxyAuthMethod" , & mut trusted_only)
230
+ . map ( |v| ( v, Cow :: Owned ( format ! ( "remote.{name}.proxyAuthMethod" ) . into ( ) ) ) )
231
+ } )
232
+ . or_else ( || {
233
+ config
234
+ . string_filter ( "http" , None , "proxyAuthMethod" , & mut trusted_only)
235
+ . map ( |v| ( v, Cow :: Borrowed ( "http.proxyAuthMethod" . into ( ) ) ) )
236
+ } ) ,
237
+ lenient,
238
+ ) ?;
184
239
opts. proxy_authenticate = opts
185
240
. proxy
186
241
. as_deref ( )
@@ -202,7 +257,7 @@ impl crate::Repository {
202
257
. map ( std:: time:: Duration :: from_millis) ;
203
258
opts. user_agent = config
204
259
. string_filter ( "http" , None , "userAgent" , & mut trusted_only)
205
- . and_then ( |v| try_cow_to_string ( v, lenient, "http.userAgent" ) . transpose ( ) )
260
+ . and_then ( |v| try_cow_to_string ( v, lenient, Cow :: Borrowed ( "http.userAgent" . into ( ) ) ) . transpose ( ) )
206
261
. transpose ( ) ?
207
262
. or_else ( || Some ( crate :: env:: agent ( ) . into ( ) ) ) ;
208
263
0 commit comments