sqlx_mysql/protocol/connect/
handshake_response.rsuse crate::io::MySqlBufMutExt;
use crate::io::{BufMutExt, ProtocolEncode};
use crate::protocol::auth::AuthPlugin;
use crate::protocol::connect::ssl_request::SslRequest;
use crate::protocol::Capabilities;
#[derive(Debug)]
pub struct HandshakeResponse<'a> {
pub database: Option<&'a str>,
pub max_packet_size: u32,
pub collation: u8,
pub username: &'a str,
pub auth_plugin: Option<AuthPlugin>,
pub auth_response: Option<&'a [u8]>,
}
impl ProtocolEncode<'_, Capabilities> for HandshakeResponse<'_> {
fn encode_with(
&self,
buf: &mut Vec<u8>,
mut context: Capabilities,
) -> Result<(), crate::Error> {
if self.auth_plugin.is_none() {
context.remove(Capabilities::PLUGIN_AUTH);
}
SslRequest {
max_packet_size: self.max_packet_size,
collation: self.collation,
}
.encode_with(buf, context)?;
buf.put_str_nul(self.username);
if context.contains(Capabilities::PLUGIN_AUTH_LENENC_DATA) {
buf.put_bytes_lenenc(self.auth_response.unwrap_or_default());
} else if context.contains(Capabilities::SECURE_CONNECTION) {
let response = self.auth_response.unwrap_or_default();
let response_len = u8::try_from(response.len())
.map_err(|_| err_protocol!("auth_response.len() too long: {}", response.len()))?;
buf.push(response_len);
buf.extend(response);
} else {
buf.push(0);
}
if context.contains(Capabilities::CONNECT_WITH_DB) {
if let Some(database) = &self.database {
buf.put_str_nul(database);
} else {
buf.push(0);
}
}
if context.contains(Capabilities::PLUGIN_AUTH) {
if let Some(plugin) = &self.auth_plugin {
buf.put_str_nul(plugin.name());
} else {
buf.push(0);
}
}
Ok(())
}
}