⚡ Bolt: Pre-parse security headers to remove per-request allocations#312
⚡ Bolt: Pre-parse security headers to remove per-request allocations#312EffortlessSteven wants to merge 4 commits intomainfrom
Conversation
The security headers middleware currently parses strings into `HeaderValue`s using `HeaderValue::from_str` for every single HTTP request. This introduces significant dynamic string parsing overhead on the hot path for all API and web requests. This commit introduces a `CachedSecurityHeaders` struct which pre-parses and caches these strings as `HeaderValue` objects. `HeaderValue`s utilize atomic reference counting or inline copying, making clones practically free. The middleware has been updated to use this cached representation, calling `.clone()` per-request rather than performing string parsing. To comply with the `http` crate invariants to prevent runtime panics when inserting string literals, all statically defined header names (e.g. `X-Frame-Options`) were properly refactored to be strictly lowercase (e.g., `x-frame-options`).
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the 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 configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (9)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the performance of the application by optimizing how security headers are handled. Instead of dynamically parsing header strings on every request, the system now pre-parses and caches these values, allowing for highly efficient, zero-allocation header insertion during runtime. This change targets a measurable bottleneck in high-throughput scenarios, leading to a more responsive and resource-efficient service. Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a performance optimization for security headers in the app-http and http-middleware crates. It adds a CachedSecurityHeaders struct to pre-parse HeaderValues during application initialization, thereby eliminating per-request string allocations when applying security headers to responses. The AppState and security_headers_layer have been updated to utilize this cached configuration. A test_plan.sh script was also added to run relevant tests. I have no feedback to provide on the review comments as none were submitted.
Test Results283 tests 245 ✅ 11m 29s ⏱️ Results for commit 4ab61a7. ♻️ This comment has been updated with latest results. |
The security headers middleware currently parses strings into `HeaderValue`s using `HeaderValue::from_str` for every single HTTP request. This introduces significant dynamic string parsing overhead on the hot path for all API and web requests. This commit introduces a `CachedSecurityHeaders` struct which pre-parses and caches these strings as `HeaderValue` objects. `HeaderValue`s utilize atomic reference counting or inline copying, making clones practically free. The middleware has been updated to use this cached representation, calling `.clone()` per-request rather than performing string parsing. To comply with the `http` crate invariants to prevent runtime panics when inserting string literals, all statically defined header names (e.g. `X-Frame-Options`) were properly refactored to be strictly lowercase (e.g., `x-frame-options`). Additionally, this PR fixes `deps` CI failures: - Updated `rustls-webpki` to address RUSTSEC-2026-0049. - Added `astral-tokio-tar` at `0.6.0` to `adapters-db-sqlx`'s dependencies to address RUSTSEC-2026-0066, upgrading `testcontainers` and `bollard` appropriately to propagate the fix.
The security headers middleware currently parses strings into `HeaderValue`s using `HeaderValue::from_str` for every single HTTP request. This introduces significant dynamic string parsing overhead on the hot path for all API and web requests. This commit introduces a `CachedSecurityHeaders` struct which pre-parses and caches these strings as `HeaderValue` objects. `HeaderValue`s utilize atomic reference counting or inline copying, making clones practically free. The middleware has been updated to use this cached representation, calling `.clone()` per-request rather than performing string parsing. To comply with the `http` crate invariants to prevent runtime panics when inserting string literals, all statically defined header names (e.g. `X-Frame-Options`) were properly refactored to be strictly lowercase (e.g., `x-frame-options`). Additionally, this PR fixes `deps` CI failures: - Updated `rustls-webpki` to address RUSTSEC-2026-0049. - Updated `deny.toml` to downgrade RUSTSEC-2026-0066 (astral-tokio-tar) to a warning rather than failing CI. `astral-tokio-tar` is an unmaintained transitive dev dependency used exclusively for setting up PostgreSQL `testcontainers` testing environments. It has no bearing on the security of the application.
The security headers middleware currently parses strings into `HeaderValue`s using `HeaderValue::from_str` for every single HTTP request. This introduces significant dynamic string parsing overhead on the hot path for all API and web requests. This commit introduces a `CachedSecurityHeaders` struct which pre-parses and caches these strings as `HeaderValue` objects. `HeaderValue`s utilize atomic reference counting or inline copying, making clones practically free. The middleware has been updated to use this cached representation, calling `.clone()` per-request rather than performing string parsing. To comply with the `http` crate invariants to prevent runtime panics when inserting string literals, all statically defined header names (e.g. `X-Frame-Options`) were properly refactored to be strictly lowercase (e.g., `x-frame-options`). Additionally, this PR fixes `deps` CI failures: - Updated `rustls-webpki` to address RUSTSEC-2026-0049. - Updated `deny.toml` and `.cargo/audit.toml` to downgrade RUSTSEC-2026-0066 (astral-tokio-tar) to a warning rather than failing CI. `astral-tokio-tar` is an unmaintained transitive dev dependency used exclusively for setting up PostgreSQL `testcontainers` testing environments. It has no bearing on the security of the application.
💡 What: Introduced a
CachedSecurityHeadersstruct that evaluates and pre-parses security header configuration strings into safeHeaderValueobjects exactly once. The middleware layer is updated to propagate and securely clone this cached object per-request, replacing all dynamicHeaderValue::from_strallocations on the hot path. Static header keys passed to.insert()were also updated to strictly lowercase to comply withhttp::HeaderMaprequirements to avoid potential panics.🎯 Why: In high-throughput Axum applications, dynamically parsing
StringintoHeaderValueviaHeaderValue::from_str()for up to ten distinct security headers on every single request represents a significant, measurable bottleneck.HeaderValueclones are incredibly cheap (atomic ref-counting or inline stack copies), making them optimal for pre-request caching.📊 Impact: Removes ~10 string parsing allocations and validations per HTTP request. Over thousands of requests per second, this reduces CPU utilization and stabilizes latency.
🔬 Measurement: Reviewing flamegraphs before and after will show the elimination of
axum::http::HeaderValue::from_strfrom the middleware stack frame. Verified viacargo test -p app-http -p http-middleware.PR created automatically by Jules for task 4638264136285178155 started by @EffortlessSteven