# 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` 1. **Added `method: Method` extractor to the handler signature:** ```rust // Before: async fn serve_file( State(state): State, Path((cxid, file_idx)): Path<(String, u32)>, Query(query): Query, headers: HeaderMap, ) -> AppResult { // After: async fn serve_file( State(state): State, Path((cxid, file_idx)): Path<(String, u32)>, Query(query): Query, headers: HeaderMap, method: Method, ) -> AppResult { ``` 2. **Skipped view-count increment for HEAD requests:** ```rust // 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 - `Method` was already imported from `axum::http::Method` at the top of the file, so no additional import was needed. - The `serve_raw_file` handler was **not** modified; it does not have the same view-increment logic and is only accessible via GET. ### Verification - `cargo check -p cgcx-server` passed successfully. ### Open Risks / Questions - None for this task. ### Recommended Next Step - Proceed with remaining tasks in the security/stability batch.