sqlx_mysql/protocol/connect/
handshake_response.rs1use crate::io::MySqlBufMutExt;
2use crate::io::{BufMutExt, ProtocolEncode};
3use crate::protocol::auth::AuthPlugin;
4use crate::protocol::connect::ssl_request::SslRequest;
5use crate::protocol::Capabilities;
6
7#[derive(Debug)]
11pub struct HandshakeResponse<'a> {
12 pub database: Option<&'a str>,
13
14 pub max_packet_size: u32,
16
17 pub collation: u8,
19
20 pub username: &'a str,
22
23 pub auth_plugin: Option<AuthPlugin>,
25
26 pub auth_response: Option<&'a [u8]>,
28}
29
30impl ProtocolEncode<'_, Capabilities> for HandshakeResponse<'_> {
31 fn encode_with(
32 &self,
33 buf: &mut Vec<u8>,
34 mut context: Capabilities,
35 ) -> Result<(), crate::Error> {
36 if self.auth_plugin.is_none() {
37 context.remove(Capabilities::PLUGIN_AUTH);
39 }
40
41 SslRequest {
43 max_packet_size: self.max_packet_size,
44 collation: self.collation,
45 }
46 .encode_with(buf, context)?;
47
48 buf.put_str_nul(self.username);
49
50 if context.contains(Capabilities::PLUGIN_AUTH_LENENC_DATA) {
51 buf.put_bytes_lenenc(self.auth_response.unwrap_or_default());
52 } else if context.contains(Capabilities::SECURE_CONNECTION) {
53 let response = self.auth_response.unwrap_or_default();
54
55 let response_len = u8::try_from(response.len())
56 .map_err(|_| err_protocol!("auth_response.len() too long: {}", response.len()))?;
57
58 buf.push(response_len);
59 buf.extend(response);
60 } else {
61 buf.push(0);
62 }
63
64 if context.contains(Capabilities::CONNECT_WITH_DB) {
65 if let Some(database) = &self.database {
66 buf.put_str_nul(database);
67 } else {
68 buf.push(0);
69 }
70 }
71
72 if context.contains(Capabilities::PLUGIN_AUTH) {
73 if let Some(plugin) = &self.auth_plugin {
74 buf.put_str_nul(plugin.name());
75 } else {
76 buf.push(0);
77 }
78 }
79
80 Ok(())
81 }
82}