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:
@@ -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 {
|
||||
|
||||
@@ -69,6 +69,8 @@ pub struct ItemContentInfo {
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct TagsQuery {
|
||||
pub tags: Option<String>,
|
||||
#[serde(default)]
|
||||
pub allow_binary: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
@@ -79,6 +81,12 @@ pub struct ListItemsQuery {
|
||||
pub count: Option<u32>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct ItemQuery {
|
||||
#[serde(default)]
|
||||
pub allow_binary: bool,
|
||||
}
|
||||
|
||||
fn check_bearer_auth(auth_str: &str, expected_password: &str) -> bool {
|
||||
auth_str.starts_with("Bearer ") && &auth_str[7..] == expected_password
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user