perf(search): clamp search page size to bound per-request memory
The main search endpoint took `limit: params.limit.unwrap_or(100)` with no ceiling, and that value flows straight into the SQL LIMIT of search_files_paginated / search_files_in_subtree. A client passing ?limit=<huge> would make Postgres return that many rows into memory and into the result cache. The suggestions endpoint already clamps (.min(20)); search did not. Cap at MAX_SEARCH_LIMIT (500). total_count still reflects the full match set (COUNT(*) OVER()), so deeper results stay reachable via offset. https://claude.ai/code/session_01UtfkS3nZF1vrF5jNAps6wV
This commit is contained in:
@@ -21,6 +21,14 @@ use std::sync::Arc;
|
|||||||
* formatting) is performed server-side. These handlers are thin HTTP
|
* formatting) is performed server-side. These handlers are thin HTTP
|
||||||
* adapters that delegate to the SearchUseCase.
|
* adapters that delegate to the SearchUseCase.
|
||||||
*/
|
*/
|
||||||
|
/// Hard cap on the search page size. The default is 100; without a ceiling a
|
||||||
|
/// client could pass `?limit=<huge>`, which flows straight into the SQL `LIMIT`
|
||||||
|
/// and would pull that many rows into memory (and into the result cache). 500
|
||||||
|
/// is a generous page for a search UI — `total_count` still reflects the full
|
||||||
|
/// match set, so deeper results stay reachable via `offset`. Mirrors the
|
||||||
|
/// suggestions endpoint, which already clamps with `.min(20)`.
|
||||||
|
const MAX_SEARCH_LIMIT: usize = 500;
|
||||||
|
|
||||||
pub struct SearchHandler;
|
pub struct SearchHandler;
|
||||||
|
|
||||||
impl SearchHandler {
|
impl SearchHandler {
|
||||||
@@ -62,7 +70,7 @@ impl SearchHandler {
|
|||||||
max_size: params.max_size,
|
max_size: params.max_size,
|
||||||
folder_id: params.folder_id,
|
folder_id: params.folder_id,
|
||||||
recursive: params.recursive.unwrap_or(true),
|
recursive: params.recursive.unwrap_or(true),
|
||||||
limit: params.limit.unwrap_or(100),
|
limit: params.limit.unwrap_or(100).min(MAX_SEARCH_LIMIT),
|
||||||
offset: params.offset.unwrap_or(0),
|
offset: params.offset.unwrap_or(0),
|
||||||
sort_by: params.sort_by.unwrap_or_else(|| "relevance".to_string()),
|
sort_by: params.sort_by.unwrap_or_else(|| "relevance".to_string()),
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user