opensrv_clickhouse/protocols/
protocol_hello.rs1use std::io::Read;
16
17use crate::binary::Encoder;
18use crate::binary::ReadEx;
19use crate::error_codes;
20use crate::errors::Error;
21use crate::errors::Result;
22use crate::errors::ServerError;
23use crate::protocols::*;
24
25#[derive(Default, Debug, Clone)]
26pub struct HelloRequest {
27 pub client_name: Vec<u8>,
28 pub client_version_major: u64,
29 pub client_version_minor: u64,
30 pub client_revision: u64,
31 pub default_database: Vec<u8>,
32
33 pub user: String,
34 pub password: Vec<u8>,
35
36 pub client_version_patch: u64,
38}
39
40impl HelloRequest {
41 pub fn read_from<R: Read>(reader: &mut R) -> Result<HelloRequest> {
42 let request = HelloRequest {
43 client_name: reader.read_len_encode_bytes()?,
44 client_version_major: reader.read_uvarint()?,
45 client_version_minor: reader.read_uvarint()?,
46 client_revision: reader.read_uvarint()?,
47 default_database: reader.read_len_encode_bytes()?,
48 user: reader.read_string()?,
49 password: reader.read_len_encode_bytes()?,
50
51 client_version_patch: 0,
52 };
53
54 if request.user.is_empty() {
55 return Err(Error::Server(ServerError {
56 name: "UNEXPECTED_PACKET_FROM_CLIENT".to_string(),
57 code: error_codes::UNEXPECTED_PACKET_FROM_CLIENT,
58 message: "Unexpected packet from client (no user in Hello package)".to_string(),
59 stack_trace: "".to_string(),
60 }));
61 }
62
63 Ok(request)
64 }
65}
66
67pub struct HelloResponse {
68 pub dbms_name: String,
69 pub dbms_version_major: u64,
70 pub dbms_version_minor: u64,
71 pub dbms_tcp_protocol_version: u64,
72 pub timezone: String,
73 pub server_display_name: String,
74 pub dbms_version_patch: u64,
75}
76
77impl HelloResponse {
78 pub fn encode(&self, encoder: &mut Encoder, client_revision: u64) -> Result<()> {
79 encoder.uvarint(SERVER_HELLO);
80
81 encoder.string(&self.dbms_name);
82 encoder.uvarint(self.dbms_version_major);
83 encoder.uvarint(self.dbms_version_minor);
84 encoder.uvarint(self.dbms_tcp_protocol_version);
85
86 if client_revision >= DBMS_MIN_REVISION_WITH_SERVER_TIMEZONE {
87 encoder.string(&self.timezone);
88 }
89
90 if client_revision >= DBMS_MIN_REVISION_WITH_SERVER_DISPLAY_NAME {
91 encoder.string(&self.server_display_name);
92 }
93
94 if client_revision >= DBMS_MIN_REVISION_WITH_VERSION_PATCH {
95 encoder.uvarint(self.dbms_version_patch);
96 }
97
98 Ok(())
99 }
100}