(
stream: S,
connection_info: &str,
db_handler: Arc<DbHandler>,
)
| 332 | } |
| 333 | |
| 334 | async fn handle_connection_generic<S>( |
| 335 | stream: S, |
| 336 | connection_info: &str, |
| 337 | db_handler: Arc<DbHandler>, |
| 338 | ) -> Result<()> |
| 339 | where |
| 340 | S: tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin + Send, |
| 341 | { |
| 342 | let codec = PostgresCodec::new(); |
| 343 | let mut framed = Framed::new(stream, codec); |
| 344 | |
| 345 | // Wait for startup message |
| 346 | let startup = match framed.next().await { |
| 347 | Some(Ok(FrontendMessage::StartupMessage(msg))) => msg, |
| 348 | Some(Ok(other)) => { |
| 349 | error!("Expected startup message, got {:?}", other); |
| 350 | return Err(anyhow::anyhow!("Protocol error: expected startup message")); |
| 351 | } |
| 352 | Some(Err(e)) => return Err(e.into()), |
| 353 | None => return Err(anyhow::anyhow!("Connection closed unexpectedly")), |
| 354 | }; |
| 355 | |
| 356 | info!("Received startup message from {}: {:?}", connection_info, startup); |
| 357 | |
| 358 | // Extract session parameters |
| 359 | let mut database = "main".to_string(); |
| 360 | let mut user = "postgres".to_string(); |
| 361 | |
| 362 | for (key, value) in &startup.parameters { |
| 363 | match key.as_str() { |
| 364 | "database" => database = value.clone(), |
| 365 | "user" => user = value.clone(), |
| 366 | _ => {} |
| 367 | } |
| 368 | } |
| 369 | |
| 370 | let session = Arc::new(SessionState::new(database.clone(), user.clone())); |
| 371 | let session_id = session.id; |
| 372 | |
| 373 | // Set the database handler for this session for proper lifecycle management |
| 374 | session.set_db_handler(db_handler.clone()).await; |
| 375 | |
| 376 | // Create a connection for this session |
| 377 | if let Err(e) = session.initialize_connection().await { |
| 378 | error!("Failed to create session connection: {}", e); |
| 379 | return Err(anyhow::anyhow!("Failed to create session connection: {}", e)); |
| 380 | } |
| 381 | |
| 382 | // Note: cleanup is now handled by SessionState Drop implementation |
| 383 | // when the session Arc is dropped |
| 384 | |
| 385 | // We'll handle cleanup at the end of the function |
| 386 | |
| 387 | // Send authentication OK |
| 388 | framed |
| 389 | .send(BackendMessage::Authentication(AuthenticationMessage::Ok)) |
| 390 | .await?; |
| 391 |
no test coverage detected