package com.github.netty.protocol.mysql.client; import com.github.netty.protocol.mysql.*; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.DecoderException; import io.netty.handler.codec.TooLongFrameException; import java.nio.charset.StandardCharsets; import java.util.EnumSet; import java.util.List; /** * */ public class ClientConnectionDecoder extends AbstractPacketDecoder implements ClientDecoder { private Session session; public ClientConnectionDecoder(Session session,int maxPacketSize) { super(maxPacketSize); this.session = session; } @Override protected void decodePacket(ChannelHandlerContext ctx, int sequenceId, ByteBuf packet, List<Object> out) { EnumSet<CapabilityFlags> clientCapabilities = CodecUtils.readIntEnumSet(packet, CapabilityFlags.class); if (!clientCapabilities.contains(CapabilityFlags.CLIENT_PROTOCOL_41)) { throw new DecoderException("MySQL client protocol 4.1 support required"); } ClientHandshakePacket.Builder response = ClientHandshakePacket.create(); response.sequenceId(sequenceId); response.addCapabilities(clientCapabilities) .maxPacketSize((int)packet.readUnsignedIntLE()); MysqlCharacterSet characterSet = MysqlCharacterSet.findById(packet.readByte()); response.characterSet(characterSet); packet.skipBytes(23); if (packet.isReadable()) { response.username(CodecUtils.readNullTerminatedString(packet, characterSet.getCharset())); EnumSet<CapabilityFlags> serverCapabilities = session.getBackendCapabilities(); EnumSet<CapabilityFlags> capabilities = EnumSet.copyOf(clientCapabilities); capabilities.retainAll(serverCapabilities); int authResponseLength; if (capabilities.contains(CapabilityFlags.CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA)) { authResponseLength = (int)CodecUtils.readLengthEncodedInteger(packet); } else if (capabilities.contains(CapabilityFlags.CLIENT_SECURE_CONNECTION)) { authResponseLength = packet.readUnsignedByte(); } else { authResponseLength = CodecUtils.findNullTermLen(packet); } response.addAuthData(packet, authResponseLength); if (capabilities.contains(CapabilityFlags.CLIENT_CONNECT_WITH_DB)) { response.database(CodecUtils.readNullTerminatedString(packet, characterSet.getCharset())); } if (capabilities.contains(CapabilityFlags.CLIENT_PLUGIN_AUTH)) { response.authPluginName(CodecUtils.readNullTerminatedString(packet, StandardCharsets.UTF_8)); } if (capabilities.contains(CapabilityFlags.CLIENT_CONNECT_ATTRS)) { long keyValueLen = CodecUtils.readLengthEncodedInteger(packet); for (int i = 0; i < keyValueLen; i++) { response.addAttribute( CodecUtils.readLengthEncodedString(packet, StandardCharsets.UTF_8), CodecUtils.readLengthEncodedString(packet, StandardCharsets.UTF_8)); } } } out.add(response.build()); } }