mirror of
https://github.com/launchbadge/sqlx.git
synced 2025-12-29 21:00:54 +00:00
87 lines
3.0 KiB
Rust
87 lines
3.0 KiB
Rust
use crate::{
|
|
io::BufMut,
|
|
mariadb::{
|
|
io::BufMutExt,
|
|
protocol::{Capabilities, Encode},
|
|
},
|
|
};
|
|
use byteorder::LittleEndian;
|
|
|
|
#[derive(Debug)]
|
|
pub struct HandshakeResponsePacket<'a> {
|
|
pub capabilities: Capabilities,
|
|
pub max_packet_size: u32,
|
|
pub client_collation: u8,
|
|
pub username: &'a str,
|
|
pub database: &'a str,
|
|
pub auth_data: Option<&'a [u8]>,
|
|
pub auth_plugin_name: Option<&'a str>,
|
|
pub connection_attrs: &'a [(&'a str, &'a str)],
|
|
}
|
|
|
|
impl<'a> Encode for HandshakeResponsePacket<'a> {
|
|
fn encode(&self, buf: &mut Vec<u8>, capabilities: Capabilities) {
|
|
// client capabilities : int<4>
|
|
buf.put_u32::<LittleEndian>(self.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 not (capabilities & CLIENT_MYSQL)
|
|
if !capabilities.contains(Capabilities::CLIENT_MYSQL) {
|
|
// extended client capabilities : int<4>
|
|
buf.put_u32::<LittleEndian>((self.capabilities.bits() >> 32) as u32);
|
|
} else {
|
|
// reserved : int<4>
|
|
buf.advance(4);
|
|
}
|
|
|
|
// username : string<NUL>
|
|
buf.put_str_nul(self.username);
|
|
|
|
// if (capabilities & PLUGIN_AUTH_LENENC_CLIENT_DATA)
|
|
let auth_data = self.auth_data.unwrap_or_default();
|
|
if capabilities.contains(Capabilities::PLUGIN_AUTH_LENENC_CLIENT_DATA) {
|
|
// authentication data : string<lenenc>
|
|
buf.put_bytes_lenenc::<LittleEndian>(auth_data);
|
|
} else if capabilities.contains(Capabilities::SECURE_CONNECTION) {
|
|
// length of authentication response : int<1>
|
|
// authentication response (length is indicated by previous field) : string<fix>
|
|
buf.put_u8(auth_data.len() as u8);
|
|
buf.put_bytes(auth_data);
|
|
} else {
|
|
// 0x00 : int<1>
|
|
buf.put_u8(0);
|
|
}
|
|
|
|
// if (capabilities & CLIENT_CONNECT_WITH_DB)
|
|
if capabilities.contains(Capabilities::CONNECT_WITH_DB) {
|
|
// default database name : string<NUL>
|
|
buf.put_str_nul(self.database);
|
|
}
|
|
|
|
// if (capabilities & CLIENT_PLUGIN_AUTH)
|
|
if capabilities.contains(Capabilities::PLUGIN_AUTH) {
|
|
// authentication plugin name : string<NUL>
|
|
buf.put_str_nul(self.auth_plugin_name.unwrap_or_default());
|
|
}
|
|
|
|
// if (capabilities & CLIENT_CONNECT_ATTRS)
|
|
if capabilities.contains(Capabilities::CONNECT_ATTRS) {
|
|
// size of connection attributes : int<lenenc>
|
|
buf.put_uint_lenenc::<LittleEndian, _>(self.connection_attrs.len() as u64);
|
|
|
|
for (key, value) in self.connection_attrs {
|
|
buf.put_str_lenenc::<LittleEndian>(key);
|
|
buf.put_str_lenenc::<LittleEndian>(value);
|
|
}
|
|
}
|
|
}
|
|
}
|