1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
use byteorder::LittleEndian;
use crate::io::BufMut;
use crate::mysql::io::BufMutExt;
use crate::mysql::protocol::{Capabilities, Encode};
// https://dev.mysql.com/doc/dev/mysql-server/8.0.12/page_protocol_connection_phase_packets_protocol_handshake_response.html
// https://mariadb.com/kb/en/connection/#handshake-response-packet
#[derive(Debug)]
pub struct HandshakeResponse<'a> {
pub max_packet_size: u32,
pub client_collation: u8,
pub username: &'a str,
pub database: &'a str,
}
impl Encode for HandshakeResponse<'_> {
fn encode(&self, buf: &mut Vec<u8>, capabilities: Capabilities) {
// client capabilities : int<4>
buf.put_u32::<LittleEndian>(capabilities.bits() as u32);
// max packet size : int<4>
buf.put_u32::<LittleEndian>(self.max_packet_size);
// client character collation : int<1>
buf.put_u8(self.client_collation);
// reserved : string<19>
buf.advance(19);
if capabilities.contains(Capabilities::MYSQL) {
// reserved : string<4>
buf.advance(4);
} else {
// extended client capabilities : int<4>
buf.put_u32::<LittleEndian>((capabilities.bits() >> 32) as u32);
}
// username : string<NUL>
buf.put_str_nul(self.username);
if capabilities.contains(Capabilities::PLUGIN_AUTH_LENENC_DATA) {
// auth_response : string<lenenc>
buf.put_str_lenenc::<LittleEndian>("");
} else {
// auth_response_length : int<1>
buf.put_u8(0);
// auth_response : string<{auth_response_length}>
}
if capabilities.contains(Capabilities::CONNECT_WITH_DB) {
// database : string<NUL>
buf.put_str_nul(self.database);
}
}
}