From d2240e1163a62f96dfb1cb99c38ffa2390d53c33 Mon Sep 17 00:00:00 2001 From: Ellie Huxtable Date: Sun, 21 May 2023 16:21:51 +0100 Subject: Allow server configured page size (#994) * Allow server configured page size * Backwards compat via semver checks * Correct header name --- atuin-server/Cargo.toml | 1 + atuin-server/src/database.rs | 5 +++-- atuin-server/src/handlers/history.rs | 17 +++++++++++++++++ atuin-server/src/handlers/status.rs | 4 ++++ atuin-server/src/lib.rs | 1 + atuin-server/src/settings.rs | 2 ++ atuin-server/src/utils.rs | 15 +++++++++++++++ 7 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 atuin-server/src/utils.rs (limited to 'atuin-server') diff --git a/atuin-server/Cargo.toml b/atuin-server/Cargo.toml index 773f3eb3..77c308b3 100644 --- a/atuin-server/Cargo.toml +++ b/atuin-server/Cargo.toml @@ -34,3 +34,4 @@ tower = "0.4" tower-http = { version = "0.3", features = ["trace"] } reqwest = { workspace = true } argon2 = "0.5.0" +semver = { workspace = true } diff --git a/atuin-server/src/database.rs b/atuin-server/src/database.rs index e7057f6b..894fab7b 100644 --- a/atuin-server/src/database.rs +++ b/atuin-server/src/database.rs @@ -14,7 +14,6 @@ use super::{ models::{History, NewHistory, NewSession, NewUser, Session, User}, }; use crate::settings::Settings; -use crate::settings::HISTORY_PAGE_SIZE; use atuin_common::utils::get_days_from_month; @@ -51,6 +50,7 @@ pub trait Database { created_after: chrono::NaiveDateTime, since: chrono::NaiveDateTime, host: &str, + page_size: i64, ) -> Result>; async fn add_history(&self, history: &[NewHistory]) -> Result<()>; @@ -271,6 +271,7 @@ impl Database for Postgres { created_after: chrono::NaiveDateTime, since: chrono::NaiveDateTime, host: &str, + page_size: i64, ) -> Result> { let res = sqlx::query_as::<_, History>( "select id, client_id, user_id, hostname, timestamp, data, created_at from history @@ -285,7 +286,7 @@ impl Database for Postgres { .bind(host) .bind(created_after) .bind(since) - .bind(HISTORY_PAGE_SIZE) + .bind(page_size) .fetch_all(&self.pool) .await?; diff --git a/atuin-server/src/handlers/history.rs b/atuin-server/src/handlers/history.rs index 3e84074c..1c9dff5f 100644 --- a/atuin-server/src/handlers/history.rs +++ b/atuin-server/src/handlers/history.rs @@ -2,6 +2,7 @@ use std::collections::HashMap; use axum::{ extract::{Path, Query, State}, + http::HeaderMap, Json, }; use http::StatusCode; @@ -13,6 +14,7 @@ use crate::{ database::Database, models::{NewHistory, User}, router::AppState, + utils::client_version_min, }; use atuin_common::api::*; @@ -41,15 +43,30 @@ pub async fn count( pub async fn list( req: Query, user: User, + headers: HeaderMap, state: State>, ) -> Result, ErrorResponseStatus<'static>> { let db = &state.0.database; + + let agent = headers + .get("user-agent") + .map_or("", |v| v.to_str().unwrap_or("")); + + let variable_page_size = client_version_min(agent, ">=15.0.0").unwrap_or(false); + + let page_size = if variable_page_size { + state.settings.page_size + } else { + 100 + }; + let history = db .list_history( &user, req.sync_ts.naive_utc(), req.history_ts.naive_utc(), &req.host, + page_size, ) .await; diff --git a/atuin-server/src/handlers/status.rs b/atuin-server/src/handlers/status.rs index 351c2dd2..97c02886 100644 --- a/atuin-server/src/handlers/status.rs +++ b/atuin-server/src/handlers/status.rs @@ -7,6 +7,8 @@ use crate::{database::Database, models::User, router::AppState}; use atuin_common::api::*; +const VERSION: &str = env!("CARGO_PKG_VERSION"); + #[instrument(skip_all, fields(user.id = user.id))] pub async fn status( user: User, @@ -35,5 +37,7 @@ pub async fn status( count, deleted, username: user.username, + version: VERSION.to_string(), + page_size: state.settings.page_size, })) } diff --git a/atuin-server/src/lib.rs b/atuin-server/src/lib.rs index 571c09bb..2a77994c 100644 --- a/atuin-server/src/lib.rs +++ b/atuin-server/src/lib.rs @@ -15,6 +15,7 @@ pub mod handlers; pub mod models; pub mod router; pub mod settings; +pub mod utils; pub async fn launch(settings: Settings, host: String, port: u16) -> Result<()> { let host = host.parse::()?; diff --git a/atuin-server/src/settings.rs b/atuin-server/src/settings.rs index b689983c..981d239f 100644 --- a/atuin-server/src/settings.rs +++ b/atuin-server/src/settings.rs @@ -15,6 +15,7 @@ pub struct Settings { pub db_uri: String, pub open_registration: bool, pub max_history_length: usize, + pub page_size: i64, pub register_webhook_url: Option, pub register_webhook_username: String, } @@ -40,6 +41,7 @@ impl Settings { .set_default("max_history_length", 8192)? .set_default("path", "")? .set_default("register_webhook_username", "")? + .set_default("page_size", 1100)? .add_source( Environment::with_prefix("atuin") .prefix_separator("_") diff --git a/atuin-server/src/utils.rs b/atuin-server/src/utils.rs new file mode 100644 index 00000000..12e9ac1b --- /dev/null +++ b/atuin-server/src/utils.rs @@ -0,0 +1,15 @@ +use eyre::Result; +use semver::{Version, VersionReq}; + +pub fn client_version_min(user_agent: &str, req: &str) -> Result { + if user_agent.is_empty() { + return Ok(false); + } + + let version = user_agent.replace("atuin/", ""); + + let req = VersionReq::parse(req)?; + let version = Version::parse(version.as_str())?; + + Ok(req.matches(&version)) +} -- cgit v1.3.1