@@ -5,19 +5,18 @@ 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.
18
16
pub fn transport_options < ' a > (
19
17
& self ,
20
18
url : impl Into < & ' a BStr > ,
19
+ remote_name : Option < & BStr > ,
21
20
) -> Result < Option < Box < dyn Any > > , crate :: config:: transport:: Error > {
22
21
let url = git_url:: parse ( url. into ( ) ) ?;
23
22
use git_url:: Scheme :: * ;
@@ -49,12 +48,15 @@ impl crate::Repository {
49
48
fn try_cow_to_string (
50
49
v : Cow < ' _ , BStr > ,
51
50
lenient : bool ,
52
- key : & ' static str ,
51
+ key : impl Into < Cow < ' static , BStr > > ,
53
52
) -> Result < Option < String > , crate :: config:: transport:: Error > {
54
53
Vec :: from ( v. into_owned ( ) )
55
54
. into_string ( )
56
55
. map ( Some )
57
- . map_err ( |err| crate :: config:: transport:: Error :: IllformedUtf8 { source : err, key } )
56
+ . map_err ( |err| crate :: config:: transport:: Error :: IllformedUtf8 {
57
+ source : err,
58
+ key : key. into ( ) ,
59
+ } )
58
60
. with_leniency ( lenient)
59
61
}
60
62
@@ -71,6 +73,7 @@ impl crate::Repository {
71
73
{
72
74
Ok ( integer_opt ( config, lenient, key, kind, filter) ?. unwrap_or ( default) )
73
75
}
76
+
74
77
fn integer_opt < T > (
75
78
config : & git_config:: File < ' static > ,
76
79
lenient : bool ,
@@ -103,6 +106,55 @@ impl crate::Repository {
103
106
. transpose ( )
104
107
. with_leniency ( lenient)
105
108
}
109
+
110
+ fn proxy_auth_method (
111
+ value_and_key : Option < ( Cow < ' _ , BStr > , Cow < ' static , BStr > ) > ,
112
+ lenient : bool ,
113
+ ) -> Result < ProxyAuthMethod , crate :: config:: transport:: Error > {
114
+ let value = value_and_key
115
+ . and_then ( |( v, k) | {
116
+ try_cow_to_string ( v, lenient, k. clone ( ) )
117
+ . map ( |v| v. map ( |v| ( v, k) ) )
118
+ . transpose ( )
119
+ } )
120
+ . transpose ( ) ?
121
+ . map ( |( method, key) | {
122
+ Ok ( match method. as_str ( ) {
123
+ "anyauth" => ProxyAuthMethod :: AnyAuth ,
124
+ "basic" => ProxyAuthMethod :: Basic ,
125
+ "digest" => ProxyAuthMethod :: Digest ,
126
+ "negotiate" => ProxyAuthMethod :: Negotiate ,
127
+ "ntlm" => ProxyAuthMethod :: Ntlm ,
128
+ _ => {
129
+ return Err ( crate :: config:: transport:: http:: Error :: InvalidProxyAuthMethod {
130
+ value : method,
131
+ key,
132
+ } )
133
+ }
134
+ } )
135
+ } )
136
+ . transpose ( ) ?
137
+ . unwrap_or_default ( ) ;
138
+ Ok ( value)
139
+ }
140
+
141
+ fn proxy (
142
+ value : Option < ( Cow < ' _ , BStr > , Cow < ' static , BStr > ) > ,
143
+ lenient : bool ,
144
+ ) -> Result < Option < String > , crate :: config:: transport:: Error > {
145
+ Ok ( value
146
+ . and_then ( |( v, k) | try_cow_to_string ( v, lenient, k. clone ( ) ) . transpose ( ) )
147
+ . transpose ( ) ?
148
+ . map ( |mut proxy| {
149
+ if !proxy. trim ( ) . is_empty ( ) && !proxy. contains ( "://" ) {
150
+ proxy. insert_str ( 0 , "http://" ) ;
151
+ proxy
152
+ } else {
153
+ proxy
154
+ }
155
+ } ) )
156
+ }
157
+
106
158
let mut opts = http:: Options :: default ( ) ;
107
159
let config = & self . config . resolved ;
108
160
let mut trusted_only = self . filter_config_section ( ) ;
@@ -113,7 +165,7 @@ impl crate::Repository {
113
165
. strings_filter ( "http" , None , "extraHeader" , & mut trusted_only)
114
166
. unwrap_or_default ( )
115
167
. into_iter ( )
116
- . map ( |v| try_cow_to_string ( v, lenient, "http.extraHeader" ) )
168
+ . map ( |v| try_cow_to_string ( v, lenient, Cow :: Borrowed ( "http.extraHeader" . into ( ) ) ) )
117
169
{
118
170
let header = header?;
119
171
if let Some ( header) = header {
@@ -149,38 +201,34 @@ impl crate::Repository {
149
201
integer ( config, lenient, "http.lowSpeedTime" , "u64" , trusted_only, 0 ) ?;
150
202
opts. low_speed_limit_bytes_per_second =
151
203
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
- }
204
+ opts. proxy = proxy (
205
+ remote_name
206
+ . and_then ( |name| {
207
+ config
208
+ . string_filter ( "remote" , Some ( name) , "proxy" , & mut trusted_only)
209
+ . map ( |v| ( v, Cow :: Owned ( format ! ( "remote.{name}.proxy" ) . into ( ) ) ) )
180
210
} )
181
- } )
182
- . transpose ( ) ?
183
- . unwrap_or_default ( ) ;
211
+ . or_else ( || {
212
+ config
213
+ . string_filter ( "http" , None , "proxy" , & mut trusted_only)
214
+ . map ( |v| ( v, Cow :: Borrowed ( "http.proxy" . into ( ) ) ) )
215
+ } ) ,
216
+ lenient,
217
+ ) ?;
218
+ opts. proxy_auth_method = proxy_auth_method (
219
+ remote_name
220
+ . and_then ( |name| {
221
+ config
222
+ . string_filter ( "remote" , Some ( name) , "proxyAuthMethod" , & mut trusted_only)
223
+ . map ( |v| ( v, Cow :: Owned ( format ! ( "remote.{name}.proxyAuthMethod" ) . into ( ) ) ) )
224
+ } )
225
+ . or_else ( || {
226
+ config
227
+ . string_filter ( "http" , None , "proxyAuthMethod" , & mut trusted_only)
228
+ . map ( |v| ( v, Cow :: Borrowed ( "http.proxyAuthMethod" . into ( ) ) ) )
229
+ } ) ,
230
+ lenient,
231
+ ) ?;
184
232
opts. proxy_authenticate = opts
185
233
. proxy
186
234
. as_deref ( )
@@ -202,7 +250,7 @@ impl crate::Repository {
202
250
. map ( std:: time:: Duration :: from_millis) ;
203
251
opts. user_agent = config
204
252
. string_filter ( "http" , None , "userAgent" , & mut trusted_only)
205
- . and_then ( |v| try_cow_to_string ( v, lenient, "http.userAgent" ) . transpose ( ) )
253
+ . and_then ( |v| try_cow_to_string ( v, lenient, Cow :: Borrowed ( "http.userAgent" . into ( ) ) ) . transpose ( ) )
206
254
. transpose ( ) ?
207
255
. or_else ( || Some ( crate :: env:: agent ( ) . into ( ) ) ) ;
208
256
0 commit comments