Skip to content

feat(bundler/cli): Add feature flag to use system certificates#24

Open
tomerqodo wants to merge 2 commits intoqodo_combined_20260121_qodo_grep_cursor_copilot_1_base_featbundler_cli_add_feature_flag_to_use_system_certificates_pr172from
qodo_combined_20260121_qodo_grep_cursor_copilot_1_head_featbundler_cli_add_feature_flag_to_use_system_certificates_pr172
Open

feat(bundler/cli): Add feature flag to use system certificates#24
tomerqodo wants to merge 2 commits intoqodo_combined_20260121_qodo_grep_cursor_copilot_1_base_featbundler_cli_add_feature_flag_to_use_system_certificates_pr172from
qodo_combined_20260121_qodo_grep_cursor_copilot_1_head_featbundler_cli_add_feature_flag_to_use_system_certificates_pr172

Conversation

@tomerqodo
Copy link
Copy Markdown

Benchmark PR from qodo-benchmark#172

@qodo-code-review
Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (3) 📎 Requirement gaps (0)

Grey Divider


Action required

1. crate_latest_version hides errors 📘 Rule violation ⛯ Reliability
Description
• The new platform-certs code path uses .call().ok()?, which silently discards the underlying HTTP
  error and returns None.
• This makes failures non-actionable (no error context for debugging) and contradicts the
  requirement to make fallible operations explicit rather than hidden.
Code

crates/tauri-cli/src/helpers/cargo_manifest.rs[R120-131]

+  #[cfg(feature = "platform-certs")]
+  let mut response = {
+    let agent = ureq::Agent::config_builder()
+      .tls_config(
+        ureq::tls::TlsConfig::builder()
+          .root_certs(ureq::tls::RootCerts::PlatformVerifier)
+          .build(),
+      )
+      .build()
+      .new_agent();
+    agent.get(&url).call().ok()?
+  };
Evidence
The checklist requires fallible operations to return Result rather than hiding errors, and to
provide meaningful context when failures occur. The added platform-certs branch explicitly converts
the HTTP call result into Option via .ok()?, dropping the error details entirely.

Rule 3: Generic: Robust Error Handling and Edge Case Management
AGENTS.md
crates/tauri-cli/src/helpers/cargo_manifest.rs[120-131]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The platform-certs HTTP request path uses `.call().ok()?`, which drops the error and returns `None`, hiding failure details.

## Issue Context
This code contacts an external service (`crates.io`). When it fails, developers need actionable error context. The compliance checklist also requires using `Result` for fallible operations instead of hiding errors.

## Fix Focus Areas
- crates/tauri-cli/src/helpers/cargo_manifest.rs[117-137]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Mirror URL drops path 🐞 Bug ✓ Correctness
Description
TAURI_BUNDLER_TOOLS_GITHUB_MIRROR support appears broken because
  generate_github_mirror_url_from_base no longer incorporates the requested GitHub URL into the
  returned mirror URL.
• When the env var is set, downloads will request only the mirror base URL (likely returning
  HTML/404) instead of the intended GitHub asset.
• This is a functional regression for users relying on the base-mirror environment variable.
Code

crates/tauri-bundler/src/utils/http_utils.rs[R34-39]

  std::env::var("TAURI_BUNDLER_TOOLS_GITHUB_MIRROR")
    .ok()
    .and_then(|cdn| Url::parse(&cdn).ok())
-    .map(|mut cdn| {
-      cdn.set_path(github_url);
+    .map(|cdn| {
      cdn.to_string()
    })
Evidence
generate_github_mirror_url_from_base ignores its github_url argument and returns only the parsed
CDN URL string. For GitHub downloads, download() uses create_agent_and_url() to compute
final_url, then performs agent.get(&final_url); with the base mirror set, final_url becomes
just the mirror base instead of a URL pointing at the asset.

crates/tauri-bundler/src/utils/http_utils.rs[33-40]
crates/tauri-bundler/src/utils/http_utils.rs[76-84]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`TAURI_BUNDLER_TOOLS_GITHUB_MIRROR` base-mirror support is broken because the computed mirror URL no longer includes the requested GitHub URL.

### Issue Context
`download()` relies on `create_agent_and_url()` to produce a `final_url` to fetch. When `TAURI_BUNDLER_TOOLS_GITHUB_MIRROR` is set, `generate_github_mirror_url_from_base()` should transform a GitHub asset URL into a mirror URL that still uniquely identifies that asset.

### Fix Focus Areas
- crates/tauri-bundler/src/utils/http_utils.rs[33-40]
- crates/tauri-bundler/src/utils/http_utils.rs[42-54]
- crates/tauri-bundler/src/utils/http_utils.rs[179-260]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Mirror bypasses platform certs 🐞 Bug ⛯ Reliability
Description
• Even with platform-certs enabled by default, mirrored GitHub downloads still use ureq::agent()
  rather than the new base_ureq_agent().
• This means users who configure GitHub mirrors won’t benefit from platform certificate verification
  (and proxy-from-env configuration) that this PR intends to provide.
• In corporate TLS environments (custom roots) or proxy-restricted networks, mirrored downloads may
  still fail unexpectedly.
Code

crates/tauri-bundler/src/utils/http_utils.rs[R52-54]

fn create_agent_and_url(url: &str) -> (ureq::Agent, String) {
-  generate_github_alternative_url(url).unwrap_or((
-    ureq::Agent::config_builder()
-      .proxy(ureq::Proxy::try_from_env())
-      .build()
-      .into(),
-    url.to_owned(),
-  ))
+  generate_github_alternative_url(url).unwrap_or((base_ureq_agent(), url.to_owned()))
+}
Evidence
create_agent_and_url() uses base_ureq_agent() only in the unwrap_or fallback. The mirror path
is produced by generate_github_alternative_url(), which still returns (ureq::agent(), alt_url),
so mirrored downloads keep using the default agent without the platform-verifier TLS config/proxy
configuration contained in base_ureq_agent().

crates/tauri-bundler/src/utils/http_utils.rs[42-54]
crates/tauri-bundler/src/utils/http_utils.rs[56-66]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
Mirrored GitHub downloads still use the default `ureq::agent()` and therefore bypass the new platform-certs TLS configuration and proxy-from-env behavior.

### Issue Context
`create_agent_and_url()` now uses `base_ureq_agent()` only when no alternative (mirror) URL is generated.

### Fix Focus Areas
- crates/tauri-bundler/src/utils/http_utils.rs[42-54]
- crates/tauri-bundler/src/utils/http_utils.rs[56-73]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (1)
4. WebView2 bypasses base agent 🐞 Bug ⛯ Reliability
Description
download_webview2_offline_installer now uses a raw ureq::get(url) call instead of the shared
  download(url) helper.
• This bypasses the PR’s new base_ureq_agent() (platform certs + proxy-from-env), so the WebView2
  offline installer download may still fail in environments that require platform trust stores or
  proxies.
• The inconsistency is particularly notable because webview2_guid_path was updated to use
  base_ureq_agent(), but the actual file download was not.
Code

crates/tauri-bundler/src/bundle/windows/util.rs[R65-68]

+    let response = ureq::get(url).call().map_err(Box::new)?;
+    let mut bytes = Vec::new();
+    response.into_body().into_reader().read_to_end(&mut bytes)?;
+    std::fs::write(&file_path, bytes)?;
Evidence
Within the same module, the redirect/URI resolution (webview2_guid_path) uses base_ureq_agent(),
but the offline installer download uses ureq::get(url) directly. The existing shared download()
helper routes through create_agent_and_url() and therefore through base_ureq_agent(), which is
the intended central point for TLS/proxy behavior.

crates/tauri-bundler/src/bundle/windows/util.rs[26-29]
crates/tauri-bundler/src/bundle/windows/util.rs[54-69]
crates/tauri-bundler/src/utils/http_utils.rs[76-84]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
WebView2 offline installer downloads bypass the new centralized ureq agent configuration (platform certs + proxy-from-env).

### Issue Context
`webview2_guid_path()` already uses `base_ureq_agent()`, but `download_webview2_offline_installer()` uses `ureq::get()` directly.

### Fix Focus Areas
- crates/tauri-bundler/src/bundle/windows/util.rs[54-69]
- crates/tauri-bundler/src/utils/http_utils.rs[52-85]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

5. return agent; unnecessary 📘 Rule violation ⛯ Reliability
Description
base_ureq_agent() uses an explicit return, which is commonly flagged by Clippy
  (needless_return) and would fail a -D warnings Clippy run.
• This creates avoidable CI noise and can block merges when Clippy warnings are treated as errors.
Code

crates/tauri-bundler/src/utils/http_utils.rs[72]

+  return agent;
Evidence
The checklist requires that Rust code produces no Clippy warnings when warnings are denied. The new
code includes an explicit return in a simple tail position, a common Clippy lint trigger
(needless_return).

AGENTS.md
crates/tauri-bundler/src/utils/http_utils.rs[56-73]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`base_ureq_agent()` ends with `return agent;`, which is likely to trigger Clippy's `needless_return` lint and can fail builds when warnings are denied.

## Issue Context
The project requires `cargo clippy -- -D warnings` to pass.

## Fix Focus Areas
- crates/tauri-bundler/src/utils/http_utils.rs[56-73]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. Unbounded read_to_end download 📘 Rule violation ⛨ Security
Description
• The new download path reads the entire HTTP response into memory via read_to_end with no maximum
  size enforcement.
• Since the response is external input, this can lead to excessive memory usage or denial-of-service
  behavior if a server returns an unexpectedly large payload.
Code

crates/tauri-bundler/src/bundle/windows/util.rs[R65-68]

+    let response = ureq::get(url).call().map_err(Box::new)?;
+    let mut bytes = Vec::new();
+    response.into_body().into_reader().read_to_end(&mut bytes)?;
+    std::fs::write(&file_path, bytes)?;
Evidence
The checklist requires external inputs to be validated/handled safely and edge cases to be managed.
The new code treats the HTTP body as unbounded input and buffers it completely in memory without
checking Content-Length or applying a cap.

Rule 6: Generic: Security-First Input Validation and Data Handling
Rule 3: Generic: Robust Error Handling and Edge Case Management
crates/tauri-bundler/src/bundle/windows/util.rs[65-68]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`download_webview2_offline_installer` reads the full HTTP response into memory without any size limit.

## Issue Context
The response body is external input. To comply with security-first input handling and robust edge case management, the code should enforce a reasonable maximum size or stream to disk.

## Fix Focus Areas
- crates/tauri-bundler/src/bundle/windows/util.rs[54-70]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



ⓘ The new review experience is currently in Beta. Learn more

Qodo Logo

.proxy(ureq::Proxy::try_from_env())
.build()
.into();
return agent;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

1. return agent; unnecessary 📘 Rule violation ⛯ Reliability

base_ureq_agent() uses an explicit return, which is commonly flagged by Clippy
  (needless_return) and would fail a -D warnings Clippy run.
• This creates avoidable CI noise and can block merges when Clippy warnings are treated as errors.
Agent prompt
## Issue description
`base_ureq_agent()` ends with `return agent;`, which is likely to trigger Clippy's `needless_return` lint and can fail builds when warnings are denied.

## Issue Context
The project requires `cargo clippy -- -D warnings` to pass.

## Fix Focus Areas
- crates/tauri-bundler/src/utils/http_utils.rs[56-73]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +120 to +131
#[cfg(feature = "platform-certs")]
let mut response = {
let agent = ureq::Agent::config_builder()
.tls_config(
ureq::tls::TlsConfig::builder()
.root_certs(ureq::tls::RootCerts::PlatformVerifier)
.build(),
)
.build()
.new_agent();
agent.get(&url).call().ok()?
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. crate_latest_version hides errors 📘 Rule violation ⛯ Reliability

• The new platform-certs code path uses .call().ok()?, which silently discards the underlying HTTP
  error and returns None.
• This makes failures non-actionable (no error context for debugging) and contradicts the
  requirement to make fallible operations explicit rather than hidden.
Agent prompt
## Issue description
The platform-certs HTTP request path uses `.call().ok()?`, which drops the error and returns `None`, hiding failure details.

## Issue Context
This code contacts an external service (`crates.io`). When it fails, developers need actionable error context. The compliance checklist also requires using `Result` for fallible operations instead of hiding errors.

## Fix Focus Areas
- crates/tauri-cli/src/helpers/cargo_manifest.rs[117-137]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +65 to +68
let response = ureq::get(url).call().map_err(Box::new)?;
let mut bytes = Vec::new();
response.into_body().into_reader().read_to_end(&mut bytes)?;
std::fs::write(&file_path, bytes)?;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

3. Unbounded read_to_end download 📘 Rule violation ⛨ Security

• The new download path reads the entire HTTP response into memory via read_to_end with no maximum
  size enforcement.
• Since the response is external input, this can lead to excessive memory usage or denial-of-service
  behavior if a server returns an unexpectedly large payload.
Agent prompt
## Issue description
`download_webview2_offline_installer` reads the full HTTP response into memory without any size limit.

## Issue Context
The response body is external input. To comply with security-first input handling and robust edge case management, the code should enforce a reasonable maximum size or stream to disk.

## Fix Focus Areas
- crates/tauri-bundler/src/bundle/windows/util.rs[54-70]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines 34 to 39
std::env::var("TAURI_BUNDLER_TOOLS_GITHUB_MIRROR")
.ok()
.and_then(|cdn| Url::parse(&cdn).ok())
.map(|mut cdn| {
cdn.set_path(github_url);
.map(|cdn| {
cdn.to_string()
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

4. Mirror url drops path 🐞 Bug ✓ Correctness

TAURI_BUNDLER_TOOLS_GITHUB_MIRROR support appears broken because
  generate_github_mirror_url_from_base no longer incorporates the requested GitHub URL into the
  returned mirror URL.
• When the env var is set, downloads will request only the mirror base URL (likely returning
  HTML/404) instead of the intended GitHub asset.
• This is a functional regression for users relying on the base-mirror environment variable.
Agent prompt
### Issue description
`TAURI_BUNDLER_TOOLS_GITHUB_MIRROR` base-mirror support is broken because the computed mirror URL no longer includes the requested GitHub URL.

### Issue Context
`download()` relies on `create_agent_and_url()` to produce a `final_url` to fetch. When `TAURI_BUNDLER_TOOLS_GITHUB_MIRROR` is set, `generate_github_mirror_url_from_base()` should transform a GitHub asset URL into a mirror URL that still uniquely identifies that asset.

### Fix Focus Areas
- crates/tauri-bundler/src/utils/http_utils.rs[33-40]
- crates/tauri-bundler/src/utils/http_utils.rs[42-54]
- crates/tauri-bundler/src/utils/http_utils.rs[179-260]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines 52 to +54
fn create_agent_and_url(url: &str) -> (ureq::Agent, String) {
generate_github_alternative_url(url).unwrap_or((
ureq::Agent::config_builder()
.proxy(ureq::Proxy::try_from_env())
.build()
.into(),
url.to_owned(),
))
generate_github_alternative_url(url).unwrap_or((base_ureq_agent(), url.to_owned()))
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

5. Mirror bypasses platform certs 🐞 Bug ⛯ Reliability

• Even with platform-certs enabled by default, mirrored GitHub downloads still use ureq::agent()
  rather than the new base_ureq_agent().
• This means users who configure GitHub mirrors won’t benefit from platform certificate verification
  (and proxy-from-env configuration) that this PR intends to provide.
• In corporate TLS environments (custom roots) or proxy-restricted networks, mirrored downloads may
  still fail unexpectedly.
Agent prompt
### Issue description
Mirrored GitHub downloads still use the default `ureq::agent()` and therefore bypass the new platform-certs TLS configuration and proxy-from-env behavior.

### Issue Context
`create_agent_and_url()` now uses `base_ureq_agent()` only when no alternative (mirror) URL is generated.

### Fix Focus Areas
- crates/tauri-bundler/src/utils/http_utils.rs[42-54]
- crates/tauri-bundler/src/utils/http_utils.rs[56-73]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +65 to +68
let response = ureq::get(url).call().map_err(Box::new)?;
let mut bytes = Vec::new();
response.into_body().into_reader().read_to_end(&mut bytes)?;
std::fs::write(&file_path, bytes)?;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

6. Webview2 bypasses base agent 🐞 Bug ⛯ Reliability

download_webview2_offline_installer now uses a raw ureq::get(url) call instead of the shared
  download(url) helper.
• This bypasses the PR’s new base_ureq_agent() (platform certs + proxy-from-env), so the WebView2
  offline installer download may still fail in environments that require platform trust stores or
  proxies.
• The inconsistency is particularly notable because webview2_guid_path was updated to use
  base_ureq_agent(), but the actual file download was not.
Agent prompt
### Issue description
WebView2 offline installer downloads bypass the new centralized ureq agent configuration (platform certs + proxy-from-env).

### Issue Context
`webview2_guid_path()` already uses `base_ureq_agent()`, but `download_webview2_offline_installer()` uses `ureq::get()` directly.

### Fix Focus Areas
- crates/tauri-bundler/src/bundle/windows/util.rs[54-69]
- crates/tauri-bundler/src/utils/http_utils.rs[52-85]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant