Skip to content

fix: harden OCSP handling for v0.1.3-rc.4#33

Merged
vansour merged 5 commits intomainfrom
release/v0.1.3-rc.4
Apr 9, 2026
Merged

fix: harden OCSP handling for v0.1.3-rc.4#33
vansour merged 5 commits intomainfrom
release/v0.1.3-rc.4

Conversation

@vansour
Copy link
Copy Markdown
Owner

@vansour vansour commented Apr 9, 2026

Summary

  • harden downstream OCSP handling so stapled responses are validated for certificate match and validity window before they are cached or served
  • clear stale or expired OCSP cache entries when refresh fails, and add regression coverage for valid, invalid, and expired response paths
  • remove the PR-Agent workflow/config from the release branch and publish the v0.1.3-rc.4 release updates

Validation

  • ./scripts/prepare-release.sh --tag v0.1.3-rc.4

Copilot AI review requested due to automatic review settings April 9, 2026 12:34
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 9, 2026

Warning

Rate limit exceeded

@vansour has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 1 minutes and 32 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 1 minutes and 32 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: b66d5ed5-ca1c-46cc-9230-749b9b76281b

📥 Commits

Reviewing files that changed from the base of the PR and between 0b9efaf and a1adaeb.

📒 Files selected for processing (1)
  • crates/rginx-http/src/state.rs
📝 Walkthrough

Walkthrough

移除 PR‑Agent 工作流与配置,升级工作区版本并更新 README,新增 OCSP 解析/验证依赖与公开验证 API,强化 OCSP 响应验证、缓存检查与刷新失败处理,扩展 OCSP 测试;删除两份 TLS 规划文档。

Changes

Cohort / File(s) Summary
工作流与配置
/.github/workflows/pr-agent.yaml, /.pr_agent.toml
完全删除 PR‑Agent 的 GitHub Actions 工作流与 .pr_agent.toml 配置,移除触发规则、权限、并发与 PR‑Agent/OpenAI 环境配置。
版本与 README
Cargo.toml, README.md
工作区版本由 0.1.3-rc.3 升级为 0.1.3-rc.4,README 中的当前版本示例与相关段落同步更新。
文档移除
docs/ssl-compat-matrix.md, docs/ssl-plan.md
删除完整的 SSL/TLS 兼容性矩阵与多阶段 TLS 路线图文档。
依赖添加
crates/rginx-app/Cargo.toml, crates/rginx-http/Cargo.toml
新增 derspkix509-ocsp 等依赖及相应特性,用于 OCSP/DER 解析与操作。
导出与公共 API
crates/rginx-http/src/lib.rs, crates/rginx-http/src/tls.rs
新增导出常量 MAX_OCSP_RESPONSE_BYTES 并公开函数 validate_ocsp_response_for_certificate
OCSP 验证实现
crates/rginx-http/src/tls/certificates.rs
新增并实现 OCSP 响应验证(解析 DER、检查 response_status、强制 response_type OID、匹配 CertId、验证 thisUpdate/nextUpdate);将 CertId 构建提取为可复用函数;加载捆绑时仅在验证通过时设置 stapled OCSP。
状态与缓存检查
crates/rginx-http/src/state.rs
扩展 OCSP 缓存检查返回值以包含 cache_error,增加对文件不存在、大小、零长度、超限、读取与验证失败的区分与错误字符串化逻辑。
刷新失败与缓存清理
crates/rginx-runtime/src/ocsp.rs
引入 handle_ocsp_refresh_failure 与原子化清空缓存的 helpers;在验证失败或刷新错误时避免写入缓存并按需清除,且正确上报错误与触发 TLS 接收器变更。
测试增强
crates/rginx-app/tests/ocsp.rs
将测试 responder 改为可注入共享可变响应体,新增集成测试(无效动态响应被拒、过期缓存在刷新失败时被清除),并添加生成 OCSP 响应、提取 CertId 与时间编码的辅助函数。

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client
    participant Cert as 证书链
    participant Req as OCSP 请求构建器
    participant Fetch as OCSP 获取器
    participant Valid as OCSP 验证器
    participant Cache as 缓存管理器
    participant State as 状态记录器

    Client->>Cert: 建立 TLS(需 Staple)
    Cert->>Req: 提供证书链
    Req->>Req: 提取 CertId,构建 OCSP 请求 DER
    Req->>Fetch: 发送 OCSP 请求
    Fetch->>Valid: 返回 OCSP 响应 DER
    Valid->>Valid: 解析 DER,检查 response_status 与 response_type
    Valid->>Valid: 匹配 CertId,验证 thisUpdate / nextUpdate(相对于 SystemTime::now())
    alt 验证成功
        Valid->>Cache: 写入或更新缓存(受 MAX_OCSP_RESPONSE_BYTES 限制)
        Cache->>State: 记录成功
        State->>Client: 提供有效 stapled OCSP
    else 验证失败或格式错误
        Valid->>Cache: 按需原子清空缓存(写入空文件并重命名)
        Cache->>State: 记录失败与清理标志
        State->>Client: 不提供或移除 stapled OCSP
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~70 minutes

Poem

🐰 我是小兔去验章,
OCSP 帧帧理清光,
时戳严查不留情,
旧缓存若坏即清仓,
小心翼翼守堆栈旁。

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.38% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed 标题准确总结了主要变更:加强OCSP处理并发布v0.1.3-rc.4版本,与所有代码改动直接相关。
Description check ✅ Passed 描述详细说明了所有关键变更:OCSP验证加强、缓存清理、测试覆盖和PR-Agent移除,与改动完全对应。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch release/v0.1.3-rc.4

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR hardens OCSP stapling handling for the v0.1.3-rc.4 release by validating fetched/stored OCSP responses against the current certificate and validity window, clearing stale cache entries on refresh failures, and updating release metadata while removing the PR-Agent workflow/config.

Changes:

  • Add OCSP response validation (certificate match + thisUpdate/nextUpdate window) before stapling/caching, and clear invalid/expired cache entries on refresh failures.
  • Extend status/snapshot OCSP cache inspection to surface cache validation errors, and add regression tests for valid/invalid/expired OCSP paths.
  • Bump version/docs references to v0.1.3-rc.4 and remove PR-Agent automation files from the branch.

Reviewed changes

Copilot reviewed 14 out of 15 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
README.md Updates displayed current version/tag examples for v0.1.3-rc.4.
docs/ssl-plan.md Removed SSL/TLS plan document from the branch.
docs/ssl-compat-matrix.md Removed SSL/TLS compatibility matrix document from the branch.
crates/rginx-runtime/src/ocsp.rs Validates OCSP responses before caching; clears stale cache on refresh failure; rebuilds TLS acceptors when cache changes.
crates/rginx-http/src/tls/certificates.rs Adds OCSP response parsing + certificate/time-window validation; ignores invalid cached staples at load; adds unit tests.
crates/rginx-http/src/tls.rs Exposes OCSP validation helper via rginx_http API.
crates/rginx-http/src/state.rs Enhances OCSP cache inspection for status snapshots by validating cached response and reporting errors.
crates/rginx-http/src/lib.rs Re-exports OCSP validation API.
crates/rginx-http/Cargo.toml Adds OCSP/DER parsing dependencies needed for validation.
crates/rginx-app/tests/ocsp.rs Adds integration coverage for invalid response rejection and expired cache clearing.
crates/rginx-app/Cargo.toml Adds test-time dependencies for constructing OCSP responses.
Cargo.toml Bumps workspace version to 0.1.3-rc.4.
Cargo.lock Locks new dependencies and version bump.
.pr_agent.toml Removes PR-Agent configuration.
.github/workflows/pr-agent.yaml Removes PR-Agent workflow.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread README.md
Comment thread crates/rginx-http/src/tls/certificates.rs
Comment thread crates/rginx-http/src/tls/certificates.rs
Comment thread crates/rginx-app/tests/ocsp.rs Outdated
Comment thread crates/rginx-http/src/state.rs Outdated
Comment thread crates/rginx-runtime/src/ocsp.rs
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (4)
crates/rginx-http/src/tls/certificates.rs (1)

369-393: 时间验证逻辑正确,可考虑添加时钟偏移容差

当前实现精确比较 thisUpdatenextUpdate。在生产环境中,服务器时钟可能存在轻微偏移,可以考虑添加少量容差(如 5 分钟)以提高健壮性。这不是阻塞问题,当前实现在大多数场景下可正常工作。

♻️ 可选:添加时钟偏移容差
+const CLOCK_SKEW_TOLERANCE: std::time::Duration = std::time::Duration::from_secs(300); // 5 minutes
+
 fn validate_ocsp_response_time(
     path: &Path,
     response: &x509_ocsp::SingleResponse,
     now: SystemTime,
 ) -> Result<()> {
     let this_update = response.this_update.0.to_system_time();
-    if this_update > now {
+    let future_tolerance = now + CLOCK_SKEW_TOLERANCE;
+    if this_update > future_tolerance {
         return Err(Error::Server(format!(
             "OCSP response for certificate `{}` is not yet valid (thisUpdate is in the future)",
             path.display()
         )));
     }
 
     if let Some(next_update) = response.next_update {
         let next_update = next_update.0.to_system_time();
-        if next_update < now {
+        let past_tolerance = now.checked_sub(CLOCK_SKEW_TOLERANCE).unwrap_or(now);
+        if next_update < past_tolerance {
             return Err(Error::Server(format!(
                 "OCSP response for certificate `{}` is expired (nextUpdate is in the past)",
                 path.display()
             )));
         }
     }
 
     Ok(())
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/rginx-http/src/tls/certificates.rs` around lines 369 - 393, The time
checks in validate_ocsp_response_time should allow a small clock skew tolerance
(e.g., 5 minutes) to avoid false positives; add use std::time::Duration, define
let skew = Duration::from_secs(300), then change the comparisons to consider
skew: treat the response as "not yet valid" only if this_update > now + skew,
and treat it as "expired" only if next_update + skew < now (when next_update is
Some). Update the error messages to mention the applied tolerance and keep
function name validate_ocsp_response_time and variables
this_update/next_update/now for locating the change.
crates/rginx-runtime/src/ocsp.rs (2)

284-287: 冗余文件读取

clear_ocsp_cache_file 在 Line 285 再次读取文件检查是否为空,但调用方 clear_invalid_ocsp_cache_file 已经在 Line 273 验证过文件非空。如果 clear_ocsp_cache_file 仅被 clear_invalid_ocsp_cache_file 调用,这个检查是冗余的。

如果此函数需要独立使用,可以考虑添加参数来跳过重复检查:

♻️ 可选的重构建议
-async fn clear_ocsp_cache_file(path: &Path) -> Result<bool, String> {
-    if tokio::fs::read(path).await.ok().is_some_and(|body| body.is_empty()) {
-        return Ok(false);
-    }
+async fn clear_ocsp_cache_file(path: &Path, skip_empty_check: bool) -> Result<bool, String> {
+    if !skip_empty_check {
+        if tokio::fs::read(path).await.ok().is_some_and(|body| body.is_empty()) {
+            return Ok(false);
+        }
+    }

然后在 clear_invalid_ocsp_cache_file 调用时传入 true

-    clear_ocsp_cache_file(cache_path).await
+    clear_ocsp_cache_file(cache_path, true).await
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/rginx-runtime/src/ocsp.rs` around lines 284 - 287, The function
clear_ocsp_cache_file performs a redundant file read to check for emptiness even
though its caller clear_invalid_ocsp_cache_file already verified the file is
non-empty; either remove the duplicate read in clear_ocsp_cache_file (trusting
the caller) or add a Boolean parameter (e.g., skip_empty_check: bool) to skip
the internal read when the caller has already validated the file, and update
clear_invalid_ocsp_cache_file to pass skip_empty_check = true so the redundant
check is avoided.

259-282: TOCTOU 竞态窗口(低风险)

clear_invalid_ocsp_cache_file 在 Line 263 读取文件、Line 277 验证、Line 281 清除之间存在时间窗口。理论上文件可能在验证后、清除前被其他进程更新为有效响应。

考虑到:

  • OCSP 刷新周期为 6 小时,并发更新概率极低
  • 最坏情况仅导致有效缓存被清除后重新获取
  • 不影响安全性

这是一个可接受的权衡。如果未来需要更严格的保证,可考虑使用文件锁或比较写入前后的内容哈希。

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/rginx-runtime/src/ocsp.rs` around lines 259 - 282, TOCTOU:
clear_invalid_ocsp_cache_file reads the cache, validates it, then clears it
allowing a race; fix by re-checking the file contents immediately before
deletion: in clear_invalid_ocsp_cache_file (and when using
rginx_http::validate_ocsp_response_for_certificate and clear_ocsp_cache_file)
after successful validation re-read cache_path and compare the new bytes (or
their hash) to the originally read body and only call clear_ocsp_cache_file when
they match; if they differ, return Ok(false). This avoids deleting a
concurrently-updated valid cache without adding complex locking; alternatively
add an advisory file lock around the read/validate/clear sequence if you prefer
stronger guarantees.
crates/rginx-app/tests/ocsp.rs (1)

369-373: 建议添加注释说明硬编码的 DER 字节

这些硬编码字节表示 sha256WithRSAEncryption 算法标识符(OID 1.2.840.113549.1.1.11),添加注释有助于维护。

📝 建议添加注释
+        // sha256WithRSAEncryption AlgorithmIdentifier (OID 1.2.840.113549.1.1.11 with NULL params)
         signature_algorithm: AlgorithmIdentifierOwned::from_der(&[
             0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05,
             0x00,
         ])
         .expect("signature algorithm should decode"),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/rginx-app/tests/ocsp.rs` around lines 369 - 373, Add an inline comment
next to the hardcoded DER byte array used in AlgorithmIdentifierOwned::from_der
for the signature_algorithm field explaining that these bytes encode the
sha256WithRSAEncryption algorithm identifier (OID 1.2.840.113549.1.1.11) so
future readers understand the meaning of the literal DER bytes; reference the
signature_algorithm assignment and AlgorithmIdentifierOwned::from_der when
adding the comment.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@crates/rginx-app/tests/ocsp.rs`:
- Around line 369-373: Add an inline comment next to the hardcoded DER byte
array used in AlgorithmIdentifierOwned::from_der for the signature_algorithm
field explaining that these bytes encode the sha256WithRSAEncryption algorithm
identifier (OID 1.2.840.113549.1.1.11) so future readers understand the meaning
of the literal DER bytes; reference the signature_algorithm assignment and
AlgorithmIdentifierOwned::from_der when adding the comment.

In `@crates/rginx-http/src/tls/certificates.rs`:
- Around line 369-393: The time checks in validate_ocsp_response_time should
allow a small clock skew tolerance (e.g., 5 minutes) to avoid false positives;
add use std::time::Duration, define let skew = Duration::from_secs(300), then
change the comparisons to consider skew: treat the response as "not yet valid"
only if this_update > now + skew, and treat it as "expired" only if next_update
+ skew < now (when next_update is Some). Update the error messages to mention
the applied tolerance and keep function name validate_ocsp_response_time and
variables this_update/next_update/now for locating the change.

In `@crates/rginx-runtime/src/ocsp.rs`:
- Around line 284-287: The function clear_ocsp_cache_file performs a redundant
file read to check for emptiness even though its caller
clear_invalid_ocsp_cache_file already verified the file is non-empty; either
remove the duplicate read in clear_ocsp_cache_file (trusting the caller) or add
a Boolean parameter (e.g., skip_empty_check: bool) to skip the internal read
when the caller has already validated the file, and update
clear_invalid_ocsp_cache_file to pass skip_empty_check = true so the redundant
check is avoided.
- Around line 259-282: TOCTOU: clear_invalid_ocsp_cache_file reads the cache,
validates it, then clears it allowing a race; fix by re-checking the file
contents immediately before deletion: in clear_invalid_ocsp_cache_file (and when
using rginx_http::validate_ocsp_response_for_certificate and
clear_ocsp_cache_file) after successful validation re-read cache_path and
compare the new bytes (or their hash) to the originally read body and only call
clear_ocsp_cache_file when they match; if they differ, return Ok(false). This
avoids deleting a concurrently-updated valid cache without adding complex
locking; alternatively add an advisory file lock around the read/validate/clear
sequence if you prefer stronger guarantees.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: d932f6a8-b7c2-4cc2-b5da-ea7fc1b246c3

📥 Commits

Reviewing files that changed from the base of the PR and between a0193a0 and f21876f.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (14)
  • .github/workflows/pr-agent.yaml
  • .pr_agent.toml
  • Cargo.toml
  • README.md
  • crates/rginx-app/Cargo.toml
  • crates/rginx-app/tests/ocsp.rs
  • crates/rginx-http/Cargo.toml
  • crates/rginx-http/src/lib.rs
  • crates/rginx-http/src/state.rs
  • crates/rginx-http/src/tls.rs
  • crates/rginx-http/src/tls/certificates.rs
  • crates/rginx-runtime/src/ocsp.rs
  • docs/ssl-compat-matrix.md
  • docs/ssl-plan.md
💤 Files with no reviewable changes (4)
  • .pr_agent.toml
  • docs/ssl-plan.md
  • docs/ssl-compat-matrix.md
  • .github/workflows/pr-agent.yaml

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/rginx-http/src/state.rs`:
- Around line 2053-2055: The current match on std::fs::metadata(path) swallows
all errors and returns (false, None, None, None); change it to only treat
NotFound as a missing cache and surface all other errors into the cache_error
slot so callers can see permission/corruption issues. Concretely, in the
metadata = match std::fs::metadata(path) block, on Err(e) check e.kind() ==
std::io::ErrorKind::NotFound and return (false, None, None, None) only in that
case; for any other error, return (false, None, None, Some(e.to_string() or
appropriate error type)) so cache_error is populated (preserve existing tuple
shape and types used elsewhere). Ensure references to the metadata variable and
the tuple return shape remain consistent with the surrounding function
(state.rs).

In `@crates/rginx-runtime/src/ocsp.rs`:
- Around line 251-257: 当前在 match clear_invalid_ocsp_cache_file(...) 的 Err 分支只返回
false 导致上层不会调用 refresh_tls_acceptors_from_current_config(),这会让已过期/失效的 stapled
OCSP 继续被已加载的 acceptor 服务;修改该分支逻辑使其在清理失败时也强制触发 acceptor 失效/重建(即将 Err
分支的“需要重建”标志设为 true 或另行返回表示“强制重建”),并在日志信息里保留 clear_error 细节;调整与
clear_invalid_ocsp_cache_file、refresh_tls_acceptors_from_current_config
相关的调用/返回值契约以确保上层能正确处理强制重建。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: e351935e-1688-4888-a0e0-2432f72c407a

📥 Commits

Reviewing files that changed from the base of the PR and between f21876f and cda330a.

📒 Files selected for processing (6)
  • README.md
  • crates/rginx-app/tests/ocsp.rs
  • crates/rginx-http/src/lib.rs
  • crates/rginx-http/src/state.rs
  • crates/rginx-http/src/tls/certificates.rs
  • crates/rginx-runtime/src/ocsp.rs
✅ Files skipped from review due to trivial changes (1)
  • README.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • crates/rginx-http/src/lib.rs
  • crates/rginx-http/src/tls/certificates.rs

Comment thread crates/rginx-http/src/state.rs Outdated
Comment thread crates/rginx-runtime/src/ocsp.rs Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/rginx-http/src/state.rs (1)

2025-2031: ⚠️ Potential issue | 🟡 Minor

不要让缓存错误覆盖 responder 根因。

Line 2025 这里把 cache_error 放在 responder_error 前面后,只要“缓存无效”和“responder 发现/解析失败”同时发生,TlsOcspStatusSnapshot.last_error 就只会暴露缓存问题,真正导致无法自动刷新的根因会被遮住。建议至少合并两类错误,或继续优先展示 responder/request 失败原因。

建议修改
-    let static_error = cache_error.or(responder_error).or_else(|| {
+    let static_error = match (cache_error, responder_error) {
+        (Some(cache_error), Some(responder_error)) => Some(format!(
+            "{responder_error}; cached OCSP staple also invalid: {cache_error}"
+        )),
+        (None, Some(responder_error)) => Some(responder_error),
+        (Some(cache_error), None) => Some(cache_error),
+        (None, None) => None,
+    }
+    .or_else(|| {
         if bundle.ocsp_staple_path.is_some() && responder_urls.is_empty() {
             Some("certificate does not expose an OCSP responder URL".to_string())
         } else {
             request_error
         }
     });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/rginx-http/src/state.rs` around lines 2025 - 2031, The current
static_error computation puts cache_error before responder_error which lets
cache misses mask the real responder/request failures (affecting
TlsOcspStatusSnapshot.last_error); change the logic in the static_error
assignment so responder_error and request_error are prioritized (e.g., check
responder_error.or(request_error) first) or combine messages when both exist
(merge cache_error with responder_error/request_error) and keep the existing
bundle.ocsp_staple_path and responder_urls checks intact; update the expression
around static_error, cache_error, responder_error, and request_error to ensure
responder/request failures are surfaced rather than being overridden by cache
errors.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/rginx-http/src/state.rs`:
- Around line 2067-2095: The snapshot code in status_snapshot currently calls
std::fs::read(path) after checking metadata.len(), which is racy and does
blocking full-file I/O; change this to a bounded, non-blocking-safe approach:
open the file and stream/read at most crate::MAX_OCSP_RESPONSE_BYTES + 1 bytes
(e.g., File::open then read_exact/read_to_end with a size cap) to detect
oversize without reading arbitrarily large data, then call
validate_ocsp_response_for_certificate on the bounded buffer; alternatively move
the whole read-and-validate work into a blocking thread via
tokio::task::spawn_blocking (or perform validation during refresh and cache the
result) so status_snapshot does not perform blocking disk I/O—update the logic
around metadata.len(), the std::fs::read call, and the cache_error construction
to use the capped stream or spawn_blocking path and preserve the existing
size/modified return shape and MAX_OCSP_RESPONSE_BYTES checks.

---

Outside diff comments:
In `@crates/rginx-http/src/state.rs`:
- Around line 2025-2031: The current static_error computation puts cache_error
before responder_error which lets cache misses mask the real responder/request
failures (affecting TlsOcspStatusSnapshot.last_error); change the logic in the
static_error assignment so responder_error and request_error are prioritized
(e.g., check responder_error.or(request_error) first) or combine messages when
both exist (merge cache_error with responder_error/request_error) and keep the
existing bundle.ocsp_staple_path and responder_urls checks intact; update the
expression around static_error, cache_error, responder_error, and request_error
to ensure responder/request failures are surfaced rather than being overridden
by cache errors.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: d3ed6753-5e8c-466d-8ed2-b1f757aa7a66

📥 Commits

Reviewing files that changed from the base of the PR and between cda330a and 0b9efaf.

📒 Files selected for processing (2)
  • crates/rginx-http/src/state.rs
  • crates/rginx-runtime/src/ocsp.rs
✅ Files skipped from review due to trivial changes (1)
  • crates/rginx-runtime/src/ocsp.rs

Comment thread crates/rginx-http/src/state.rs
@vansour vansour merged commit b90d0df into main Apr 9, 2026
4 checks passed
@vansour vansour deleted the release/v0.1.3-rc.4 branch April 9, 2026 13:37
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.

2 participants