2.1 KiB
2.1 KiB
Agent 1: Security & Stability Findings
Task I: Fix serve_file HEAD-request view-count leak
Problem
The serve_file handler in crates/cgcx-server/src/main.rs incremented the view_count on every request, including HEAD requests. This caused password-protected or auto-destroy content to return 410 Gone on the first real GET because a prior HEAD request (e.g., from a link preview or browser prefetch) had already consumed the single allowed view.
Changes Made
File: crates/cgcx-server/src/main.rs
-
Added
method: Methodextractor to the handler signature:// Before: async fn serve_file( State(state): State<AppState>, Path((cxid, file_idx)): Path<(String, u32)>, Query(query): Query<FileQuery>, headers: HeaderMap, ) -> AppResult<impl IntoResponse> { // After: async fn serve_file( State(state): State<AppState>, Path((cxid, file_idx)): Path<(String, u32)>, Query(query): Query<FileQuery>, headers: HeaderMap, method: Method, ) -> AppResult<impl IntoResponse> { -
Skipped view-count increment for HEAD requests:
// Before: let is_range = range.is_some(); let is_conditional = headers.contains_key(header::IF_NONE_MATCH); if !is_range && !is_conditional { let new_views = repo.increment_views(&content_id).await?; // After: let is_range = range.is_some(); let is_conditional = headers.contains_key(header::IF_NONE_MATCH); let is_head = method == Method::HEAD; if !is_range && !is_conditional && !is_head { let new_views = repo.increment_views(&content_id).await?;
Notes
Methodwas already imported fromaxum::http::Methodat the top of the file, so no additional import was needed.- The
serve_raw_filehandler was not modified; it does not have the same view-increment logic and is only accessible via GET.
Verification
cargo check -p cgcx-serverpassed successfully.
Open Risks / Questions
- None for this task.
Recommended Next Step
- Proceed with remaining tasks in the security/stability batch.