mcp: evict expired transport sessions

This commit is contained in:
a.tolmachev
2026-05-02 08:26:59 +00:00
parent 77f83a1dc1
commit fdad20a8d1
4 changed files with 204 additions and 12 deletions
+72 -2
View File
@@ -158,7 +158,10 @@ mod tests {
use tokio::time::sleep;
use tracing_subscriber::{filter::LevelFilter, fmt::MakeWriter, prelude::*};
use crate::{app::build_app, session::InMemorySessionStore};
use crate::{
app::build_app,
session::{InMemorySessionStore, SharedSessionStore, TransportSessionStore},
};
fn test_workspace_id() -> WorkspaceId {
WorkspaceId::new("ws_default")
@@ -222,6 +225,22 @@ mod tests {
refresh_interval: Duration,
public_base_url: Option<String>,
rate_limit_config: RequestRateLimitConfig,
) -> axum::Router {
build_test_app_with_store(
registry,
refresh_interval,
public_base_url,
rate_limit_config,
std::sync::Arc::new(InMemorySessionStore::default()),
)
}
fn build_test_app_with_store(
registry: PostgresRegistry,
refresh_interval: Duration,
public_base_url: Option<String>,
rate_limit_config: RequestRateLimitConfig,
sessions: SharedSessionStore,
) -> axum::Router {
build_app(
registry,
@@ -230,7 +249,7 @@ mod tests {
SecretCrypto::new("test-master-key").unwrap(),
RuntimeExecutor::new(),
RequestRateLimiter::new(rate_limit_config),
std::sync::Arc::new(InMemorySessionStore::default()),
sessions,
)
}
@@ -877,6 +896,57 @@ mod tests {
);
}
#[tokio::test]
async fn get_returns_not_found_for_expired_transport_session() {
let registry = test_registry().await;
publish_agent_with_bindings(&registry, "sales-expired-session", vec![]).await;
let api_key = create_platform_api_key(
&registry,
"mcp-expired-session",
&[PlatformApiKeyScope::Read],
)
.await;
let session_store = Arc::new(InMemorySessionStore::default());
let session_id = session_store
.create(
"2025-11-25",
test_workspace_slug(),
"sales-expired-session",
OffsetDateTime::parse("2026-05-01T10:00:00Z", &Rfc3339).unwrap(),
Some(OffsetDateTime::parse("2026-05-01T10:00:01Z", &Rfc3339).unwrap()),
)
.await
.unwrap();
session_store
.mark_initialized(
&session_id,
OffsetDateTime::parse("2026-05-01T10:00:01Z", &Rfc3339).unwrap(),
)
.await
.unwrap();
let base_url = spawn_mcp_server(build_test_app_with_store(
registry,
Duration::from_millis(0),
Some("https://crank.example.com".to_owned()),
RequestRateLimitConfig::new(10_000, 10_000).unwrap(),
session_store,
))
.await;
let client = reqwest::Client::new();
let response = client
.get(agent_mcp_url(&base_url, "sales-expired-session"))
.header(header::ACCEPT, "text/event-stream")
.header(header::AUTHORIZATION, format!("Bearer {api_key}"))
.header("MCP-Session-Id", &session_id)
.header("MCP-Protocol-Version", "2025-11-25")
.send()
.await
.unwrap();
assert_eq!(response.status(), reqwest::StatusCode::NOT_FOUND);
}
#[tokio::test]
async fn get_requires_session_header() {
let registry = test_registry().await;