diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-04 13:59:49 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-04 13:59:49 +0900 |
| commit | e6e4f6f6319b39ba3020f96d070b637054c04b6a (patch) | |
| tree | 216423fc61716825f1eded1163e17264dbff3ea1 /crates/mozart/src/commands/config_helpers.rs | |
| parent | 30b222e7324e933f1e1bde5c5e34d588e36adbaa (diff) | |
| download | php-mozart-e6e4f6f6319b39ba3020f96d070b637054c04b6a.tar.gz php-mozart-e6e4f6f6319b39ba3020f96d070b637054c04b6a.tar.zst php-mozart-e6e4f6f6319b39ba3020f96d070b637054c04b6a.zip | |
feat(http): honor config.cafile and config.capath
Composer's config.cafile/config.capath were accepted by the config
command but ignored by every HTTP request. Centralize reqwest client
construction in mozart_core::http, pre-load the configured CA bundle
at startup, and route every callsite (registry, vcs drivers, diagnose,
self-update) through the shared builder so user-supplied roots are
actually used during HTTPS verification.
Diffstat (limited to 'crates/mozart/src/commands/config_helpers.rs')
| -rw-r--r-- | crates/mozart/src/commands/config_helpers.rs | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/crates/mozart/src/commands/config_helpers.rs b/crates/mozart/src/commands/config_helpers.rs index 9b60129..422db4d 100644 --- a/crates/mozart/src/commands/config_helpers.rs +++ b/crates/mozart/src/commands/config_helpers.rs @@ -68,6 +68,53 @@ pub(crate) fn working_dir(cli: &super::Cli) -> anyhow::Result<PathBuf> { } } +/// Read TLS-related options (`config.cafile`, `config.capath`) from the merged +/// global + local config. Local values override global. Relative paths are +/// resolved against the directory of the config file that defined them. +pub(crate) fn load_tls_options(cli: &super::Cli) -> mozart_core::http::TlsOptions { + let mut opts = mozart_core::http::TlsOptions::default(); + + let home = composer_home(); + apply_tls_from_file(&home.join("config.json"), &home, &mut opts); + + if let Ok(wd) = working_dir(cli) { + apply_tls_from_file(&wd.join("composer.json"), &wd, &mut opts); + } + + opts +} + +fn apply_tls_from_file(path: &Path, base_dir: &Path, opts: &mut mozart_core::http::TlsOptions) { + let Ok(content) = std::fs::read_to_string(path) else { + return; + }; + let Ok(json) = serde_json::from_str::<serde_json::Value>(&content) else { + return; + }; + let Some(cfg) = json.get("config").and_then(|v| v.as_object()) else { + return; + }; + if let Some(s) = cfg.get("cafile").and_then(|v| v.as_str()) + && !s.is_empty() + { + opts.cafile = Some(resolve_relative(s, base_dir)); + } + if let Some(s) = cfg.get("capath").and_then(|v| v.as_str()) + && !s.is_empty() + { + opts.capath = Some(resolve_relative(s, base_dir)); + } +} + +fn resolve_relative(path: &str, base: &Path) -> PathBuf { + let p = Path::new(path); + if p.is_absolute() { + p.to_path_buf() + } else { + base.join(p) + } +} + /// Read a JSON file as `serde_json::Value`. /// If the file does not exist, return a default skeleton: /// `{"config": {}}` for global files, `{}` for local. |
