@@ -190,22 +190,92 @@ fn amend_authentication_hints(
190190pub fn open_repo ( repo_path : & std:: path:: Path , config : & Config ) -> CargoResult < git:: Repository > {
191191 git:: open_opts ( repo_path, {
192192 let mut opts = git:: open:: Options :: default ( ) ;
193- let timeout = HttpTimeout :: new ( config) ?;
194-
195193 // We need `git_binary` configuration as well for being able to see credential helpers
196194 // that are configured with the `git` installation itself.
197195 // However, this is slow on windows (~150ms) and most people won't need it as they use the
198196 // standard index which won't ever need authentication.
199197 // TODO: This is certainly something to make configurable, at the very least on windows.
200198 // Maybe it's also something that could be cached, all we need is the path to the configuration file
201199 // 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.
203205 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) ?)
209209 } )
210210 . map_err ( Into :: into)
211211}
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