@@ -190,22 +190,92 @@ fn amend_authentication_hints(
190
190
pub fn open_repo ( repo_path : & std:: path:: Path , config : & Config ) -> CargoResult < git:: Repository > {
191
191
git:: open_opts ( repo_path, {
192
192
let mut opts = git:: open:: Options :: default ( ) ;
193
- let timeout = HttpTimeout :: new ( config) ?;
194
-
195
193
// We need `git_binary` configuration as well for being able to see credential helpers
196
194
// that are configured with the `git` installation itself.
197
195
// However, this is slow on windows (~150ms) and most people won't need it as they use the
198
196
// standard index which won't ever need authentication.
199
197
// TODO: This is certainly something to make configurable, at the very least on windows.
200
198
// Maybe it's also something that could be cached, all we need is the path to the configuration file
201
199
// which usually doesn't change unless the installation changes. Maybe something keyed by the location of the
202
- // binary along with its fingerprint.
200
+ // binary along with its fingerprint, without doing much work unless the modification
201
+ // time of the binary changes to signal an update.
202
+ // TODO(QUESTION): all HTTP options set here might not actually be used if the user has per-URL options set which override these.
203
+ // To me this seems like an advantage. If it's not, there should be a way to tell `gitoxide` not to look for URL
204
+ // specific overrides.
203
205
opts. permissions . config = git:: permissions:: Config :: all ( ) ;
204
- opts. config_overrides ( [
205
- format ! ( "gitoxide.http.connectTimeout={}" , timeout. dur. as_millis( ) ) ,
206
- format ! ( "http.lowSpeedLimit={}" , timeout. low_speed_limit) ,
207
- format ! ( "http.lowSpeedTime={}" , timeout. dur. as_secs( ) ) ,
208
- ] )
206
+ opts. permissions . config . git_binary = !cfg ! ( windows) ; // TODO: make this configurable maybe? It's just slow on windows to run a program once per `cargo` invocation.
207
+ opts. with ( git:: sec:: Trust :: Full )
208
+ . config_overrides ( cargo_config_to_gitoxide_overrides ( config) ?)
209
209
} )
210
210
. map_err ( Into :: into)
211
211
}
212
+
213
+ fn cargo_config_to_gitoxide_overrides ( config : & Config ) -> CargoResult < Vec < String > > {
214
+ let timeout = HttpTimeout :: new ( config) ?;
215
+ let http = config. http_config ( ) ?;
216
+
217
+ let mut values = vec ! [
218
+ format!( "gitoxide.http.connectTimeout={}" , timeout. dur. as_millis( ) ) ,
219
+ format!( "http.lowSpeedLimit={}" , timeout. low_speed_limit) ,
220
+ format!( "http.lowSpeedTime={}" , timeout. dur. as_secs( ) ) ,
221
+ ] ;
222
+ if let Some ( proxy) = & http. proxy {
223
+ values. push ( format ! ( "http.proxy={}" , proxy) ) ;
224
+ }
225
+ if let Some ( check_revoke) = http. check_revoke {
226
+ values. push ( format ! ( "http.schannelCheckRevoke={}" , check_revoke) ) ;
227
+ }
228
+ if let Some ( cainfo) = & http. cainfo {
229
+ values. push ( format ! (
230
+ "http.sslCAInfo={}" ,
231
+ cainfo. resolve_path( config) . display( )
232
+ ) ) ;
233
+ }
234
+ if let Some ( user_agent) = & http. user_agent {
235
+ values. push ( format ! ( "http.userAgent={}" , user_agent) ) ;
236
+ }
237
+ if let Some ( ssl_version) = & http. ssl_version {
238
+ use crate :: util:: config:: SslVersionConfig ;
239
+ fn checked_version_config_value (
240
+ version : Option < & str > ,
241
+ key : & str ,
242
+ out : & mut Vec < String > ,
243
+ ) -> CargoResult < ( ) > {
244
+ version. map_or ( Ok ( curl:: easy:: SslVersion :: Default ) , |version| {
245
+ crate :: ops:: registry:: to_ssl_version ( version)
246
+ } ) ?;
247
+ out. push ( format ! ( "{key}={}" , version. unwrap_or( "default" ) ) ) ;
248
+ Ok ( ( ) )
249
+ }
250
+ match ssl_version {
251
+ SslVersionConfig :: Single ( version) => {
252
+ checked_version_config_value ( Some ( & version) , "http.sslVersion" , & mut values) ?;
253
+ }
254
+ SslVersionConfig :: Range ( range) => {
255
+ checked_version_config_value (
256
+ range. min . as_deref ( ) ,
257
+ "gitoxide.http.sslVersionMin" ,
258
+ & mut values,
259
+ ) ?;
260
+ checked_version_config_value (
261
+ range. max . as_deref ( ) ,
262
+ "gitoxide.http.sslVersionMax" ,
263
+ & mut values,
264
+ ) ?;
265
+ }
266
+ }
267
+ }
268
+ if let Some ( debug) = http. debug {
269
+ values. push ( format ! ( "gitoxide.http.verbose={debug}" ) ) ;
270
+ }
271
+ if let Some ( multiplexing) = http. multiplexing {
272
+ let http_version = multiplexing. then ( || "HTTP/2" ) . unwrap_or ( "HTTP/1.1" ) ;
273
+ // Note: the HTTP version itself should automatically make multiplexing available.
274
+ // It's unclear at this time if it does affect performance of fetches measurably.
275
+ // In `curl`, it appears special support via a `Multi` handle is needed which also doesn't
276
+ // exist in `gitoxide` - each fetch is probably its own connection that way.
277
+ values. push ( format ! ( "http.version={http_version}" ) ) ;
278
+ }
279
+
280
+ Ok ( values)
281
+ }
0 commit comments