feat: add optional allow_binary parameter to item handlers

Co-authored-by: aider (openai/andrew/openrouter/anthropic/claude-sonnet-4) <aider@aider.chat>
This commit is contained in:
Andrew Phillips
2025-08-13 13:25:27 -03:00
parent 07ea7ec5a4
commit 243e77fba4
2 changed files with 19 additions and 8 deletions

View File

@@ -13,7 +13,7 @@ use anyhow::{Result, anyhow};
use crate::compression_engine::{CompressionType, get_compression_engine};
use crate::db;
use crate::modes::server::common::{AppState, ApiResponse, ItemInfo, ItemContentInfo, TagsQuery, ListItemsQuery};
use crate::modes::server::common::{AppState, ApiResponse, ItemInfo, ItemContentInfo, TagsQuery, ListItemsQuery, ItemQuery};
use crate::common::is_binary::is_binary;
#[utoipa::path(
@@ -211,7 +211,8 @@ pub async fn handle_delete_item(
(status = 500, description = "Internal server error - Failed to retrieve item content")
),
params(
("tags" = Option<String>, Query, description = "Comma-separated list of tags to filter by (e.g., 'important,work'). If specified, returns the latest item matching ALL tags.")
("tags" = Option<String>, Query, description = "Comma-separated list of tags to filter by (e.g., 'important,work'). If specified, returns the latest item matching ALL tags."),
("allow_binary" = Option<bool>, Query, description = "Whether to include content for binary files (default: false). When false, binary files will only return metadata.")
),
security(
("bearerAuth" = [])
@@ -240,7 +241,7 @@ pub async fn handle_get_item_latest(
};
if let Some(item) = item {
match get_item_content_info(&item, &state.data_dir, &mut *conn).await {
match get_item_content_info(&item, &state.data_dir, &mut *conn, params.allow_binary).await {
Ok(content_info) => {
let response = ApiResponse {
success: true,
@@ -275,7 +276,8 @@ pub async fn handle_get_item_latest(
(status = 500, description = "Internal server error - Failed to retrieve item content")
),
params(
("item_id" = i64, Path, description = "Unique identifier of the item to retrieve (must be positive)")
("item_id" = i64, Path, description = "Unique identifier of the item to retrieve (must be positive)"),
("allow_binary" = Option<bool>, Query, description = "Whether to include content for binary files (default: false). When false, binary files will only return metadata.")
),
security(
("bearerAuth" = [])
@@ -285,6 +287,7 @@ pub async fn handle_get_item_latest(
pub async fn handle_get_item(
State(state): State<AppState>,
Path(item_id): Path<i64>,
Query(params): Query<ItemQuery>,
) -> Result<Json<ApiResponse<ItemContentInfo>>, StatusCode> {
// Validate that item ID is positive to prevent path traversal issues
if item_id <= 0 {
@@ -297,7 +300,7 @@ pub async fn handle_get_item(
warn!("Failed to get item {} for content: {}", item_id, e);
StatusCode::INTERNAL_SERVER_ERROR
})? {
match get_item_content_info(&item, &state.data_dir, &mut *conn).await {
match get_item_content_info(&item, &state.data_dir, &mut *conn, params.allow_binary).await {
Ok(content_info) => {
let response = ApiResponse {
success: true,
@@ -453,7 +456,7 @@ async fn get_item_content(item: &db::Item, data_dir: &PathBuf) -> Result<String>
Ok(content)
}
async fn get_item_content_info(item: &db::Item, data_dir: &PathBuf, conn: &mut rusqlite::Connection) -> Result<ItemContentInfo> {
async fn get_item_content_info(item: &db::Item, data_dir: &PathBuf, conn: &mut rusqlite::Connection, allow_binary: bool) -> Result<ItemContentInfo> {
let item_id = item.id.ok_or_else(|| anyhow!("Item missing ID"))?;
// Validate that item ID is positive to prevent path traversal issues
@@ -487,8 +490,8 @@ async fn get_item_content_info(item: &db::Item, data_dir: &PathBuf, conn: &mut r
is_binary(&buffer[..bytes_read])
};
// Get content if not binary
let content = if is_binary {
// Get content if not binary or if binary is allowed
let content = if is_binary && !allow_binary {
None
} else {
match get_item_content(item, data_dir).await {