From dbd0ef397015fa2acd65758975a72ffb7b35a36e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jind=C5=99ich=20Moravec?= Date: Mon, 11 Dec 2023 16:54:41 +0100 Subject: [PATCH] feat(proto): add server handshake handler --- proto/src/handshake/mod.rs | 1 + proto/src/handshake/server.rs | 59 +++++++++++++++++++++++++++++++++++ proto/src/lib.rs | 1 + 3 files changed, 61 insertions(+) create mode 100644 proto/src/handshake/mod.rs create mode 100644 proto/src/handshake/server.rs diff --git a/proto/src/handshake/mod.rs b/proto/src/handshake/mod.rs new file mode 100644 index 0000000..74f47ad --- /dev/null +++ b/proto/src/handshake/mod.rs @@ -0,0 +1 @@ +pub mod server; diff --git a/proto/src/handshake/server.rs b/proto/src/handshake/server.rs new file mode 100644 index 0000000..660ea0c --- /dev/null +++ b/proto/src/handshake/server.rs @@ -0,0 +1,59 @@ +use crate::message::backend::{ + AuthenticationOkData, BackendKeyDataData, BackendMessage, ParameterStatusData, + ReadyForQueryData, +}; +use crate::message::special::{SpecialMessage, StartupMessageData}; +use crate::reader::frontend::FrontendProtoReader; +use crate::writer::backend::BackendProtoWriter; +use crate::writer::protowriter::ProtoFlush; + +pub async fn do_server_handshake( + writer: &mut (impl BackendProtoWriter + ProtoFlush), + reader: &mut impl FrontendProtoReader, + name: &str, + process: i32, + secret: i32, +) -> anyhow::Result { + match &reader.peek_special_message().await? { + Some(msg @ SpecialMessage::SSLRequest) => { + reader.consume_special_message(msg).await?; + writer.write_ssl_reject().await?; + writer.flush().await?; + } + _ => { + // No SSL request + } + } + + let startup_message = match &reader.peek_special_message().await? { + Some(msg @ SpecialMessage::StartupMessage(data)) => { + reader.consume_special_message(msg).await?; + data.clone() + } + _ => { + return Err(anyhow::anyhow!("Expected Startup Message")); + } + }; + + writer + .write_proto(BackendMessage::from(AuthenticationOkData { status: 0 })) + .await?; + + writer + .write_proto(BackendMessage::from(ParameterStatusData { + name: "server_version".to_string().into(), + value: format!("16.0 ({name})").into(), + })) + .await?; + + writer + .write_proto(BackendMessage::from(BackendKeyDataData { process, secret })) + .await?; + + writer + .write_proto(BackendMessage::from(ReadyForQueryData { status: b'I' })) + .await?; + + writer.flush().await?; + Ok(startup_message) +} diff --git a/proto/src/lib.rs b/proto/src/lib.rs index c964d21..69afed6 100644 --- a/proto/src/lib.rs +++ b/proto/src/lib.rs @@ -1,3 +1,4 @@ +pub mod handshake; pub mod message; pub mod reader; pub mod writer;