All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.netty.protocol.mysql.server.ServerPacketEncoder Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2016 The Netty Project
 *
 * The Netty Project licenses this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

package com.github.netty.protocol.mysql.server;

import com.github.netty.protocol.mysql.*;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.channel.ChannelHandlerContext;

import java.nio.charset.Charset;
import java.util.EnumSet;

/**
 *
 */
public class ServerPacketEncoder extends AbstractPacketEncoder {
    private Session session;

    public ServerPacketEncoder(Session session) {
        this.session = session;
    }

    @Override
    protected void encodePacket(ChannelHandlerContext ctx, ServerPacket packet, ByteBuf buf) {
        EnumSet capabilities = session.getFrontendCapabilities();
        Charset serverCharset = session.getServerCharset().getCharset();
        if (packet instanceof ServerColumnCountPacket) {
            encodeColumnCount((ServerColumnCountPacket) packet, buf);
        } else if (packet instanceof ServerColumnDefinitionPacket) {
            encodeColumnDefinition(serverCharset, (ServerColumnDefinitionPacket) packet, buf);
        } else if (packet instanceof ServerEofPacket) {
            encodeEofResponse(capabilities, (ServerEofPacket) packet, buf);
        } else if (packet instanceof ServerHandshakePacket) {
            encodeHandshake((ServerHandshakePacket) packet, buf);
        } else if (packet instanceof ServerOkPacket) {
            encodeOkResponse(capabilities, serverCharset, (ServerOkPacket) packet, buf);
        } else if (packet instanceof ServerResultsetRowPacket) {
            encodeResultsetRow(serverCharset, (ServerResultsetRowPacket) packet, buf);
        } else if (packet instanceof ServerErrorPacket) {
            encodeError(serverCharset, (ServerErrorPacket) packet, buf);
        } else {
            throw new IllegalStateException("Unknown packet type: " + packet.getClass());
        }
    }

    protected void encodeColumnCount(ServerColumnCountPacket columnCount, ByteBuf buf) {
        CodecUtils.writeLengthEncodedInt(buf, (long) columnCount.getFieldCount());
    }

    protected void encodeColumnDefinition(Charset serverCharset, ServerColumnDefinitionPacket packet, ByteBuf buf) {
        CodecUtils.writeLengthEncodedString(buf, packet.getCatalog(), serverCharset);
        CodecUtils.writeLengthEncodedString(buf, packet.getSchema(), serverCharset);
        CodecUtils.writeLengthEncodedString(buf, packet.getTable(), serverCharset);
        CodecUtils.writeLengthEncodedString(buf, packet.getOrgTable(), serverCharset);
        CodecUtils.writeLengthEncodedString(buf, packet.getName(), serverCharset);
        CodecUtils.writeLengthEncodedString(buf, packet.getOrgName(), serverCharset);
        buf.writeByte(0x0c);
        buf.writeShortLE(packet.getCharacterSet().getId())
                .writeIntLE((int) packet.getColumnLength())
                .writeByte(packet.getType().getValue())
                .writeShortLE((int) CodecUtils.toLong(packet.getFlags()))
                .writeByte(packet.getDecimals())
                .writeShort(0);
        // TODO Add default values for COM_FIELD_LIST
    }

    protected void encodeEofResponse(EnumSet capabilities, ServerEofPacket eof, ByteBuf buf) {
        buf.writeByte(0xfe);
        if (capabilities.contains(CapabilityFlags.CLIENT_PROTOCOL_41)) {
            buf.writeShortLE(eof.getWarnings())
                    .writeShortLE((int) CodecUtils.toLong(eof.getStatusFlags()));
        }
    }

    protected void encodeHandshake(ServerHandshakePacket handshake, ByteBuf buf) {
        buf.writeByte(handshake.getProtocolVersion())
                .writeBytes(handshake.getServerVersion().array())
                .writeByte(Constants.NUL_BYTE)
                .writeIntLE(handshake.getConnectionId())
                .writeBytes(handshake.getAuthPluginData(), Constants.AUTH_PLUGIN_DATA_PART1_LEN)
                .writeByte(Constants.NUL_BYTE)
                .writeShortLE((int) CodecUtils.toLong(handshake.getCapabilities()))
                .writeByte(handshake.getCharacterSet().getId())
                .writeShortLE((int) CodecUtils.toLong(handshake.getServerStatus()))
                .writeShortLE((int) (CodecUtils.toLong(handshake.getCapabilities()) >> Short.SIZE));
        if (handshake.getCapabilities().contains(CapabilityFlags.CLIENT_PLUGIN_AUTH)) {
            buf.writeByte(handshake.getAuthPluginData().readableBytes() + Constants.AUTH_PLUGIN_DATA_PART1_LEN);
        } else {
            buf.writeByte(Constants.NUL_BYTE);
        }
        buf.writeZero(Constants.HANDSHAKE_RESERVED_BYTES);
        if (handshake.getCapabilities().contains(CapabilityFlags.CLIENT_SECURE_CONNECTION)) {
            int padding = Constants.AUTH_PLUGIN_DATA_PART2_MIN_LEN - handshake.getAuthPluginData().readableBytes();
            buf.writeBytes(handshake.getAuthPluginData());
            if (padding > 0) {
                buf.writeZero(padding);
            }
        }
        if (handshake.getCapabilities().contains(CapabilityFlags.CLIENT_PLUGIN_AUTH)) {
            ByteBufUtil.writeUtf8(buf, handshake.getAuthPluginName());
            buf.writeByte(Constants.NUL_BYTE);
        }
    }

    protected void encodeOkResponse(EnumSet capabilities, Charset serverCharset, ServerOkPacket response, ByteBuf buf) {
        buf.writeByte(0);
        CodecUtils.writeLengthEncodedInt(buf, response.getAffectedRows());
        CodecUtils.writeLengthEncodedInt(buf, response.getLastInsertId());
        if (capabilities.contains(CapabilityFlags.CLIENT_PROTOCOL_41)) {
            buf.writeShortLE((int) CodecUtils.toLong(response.getStatusFlags()))
                    .writeShortLE(response.getWarnings());

        } else if (capabilities.contains(CapabilityFlags.CLIENT_TRANSACTIONS)) {
            buf.writeShortLE((int) CodecUtils.toLong(response.getStatusFlags()));
        }
        if (capabilities.contains(CapabilityFlags.CLIENT_SESSION_TRACK)) {
            CodecUtils.writeLengthEncodedString(buf, response.getInfo(), serverCharset);
            if (response.getStatusFlags().contains(ServerStatusFlag.SESSION_STATE_CHANGED)) {
                CodecUtils.writeLengthEncodedString(buf, response.getSessionStateChanges(), serverCharset);
            }
        } else {
            if (response.getInfo() != null) {
                buf.writeCharSequence(response.getInfo(), serverCharset);
            }
        }
    }

    protected void encodeResultsetRow(Charset serverCharset, ServerResultsetRowPacket packet, ByteBuf buf) {
        for (String value : packet.getValues()) {
            CodecUtils.writeLengthEncodedString(buf, value, serverCharset);
        }
    }

    protected void encodeError(Charset serverCharset, ServerErrorPacket packet, ByteBuf buffer) {
        String message = packet.getMessage();
        if (message == null) {
            message = "";
        }
        byte[] messageBytes = message.getBytes(serverCharset);

//		CodecUtils.writeUB3(buffer, messageBytes.length);
//		buffer.writeByte(packet.getSequenceId());
        buffer.writeByte((byte) Constants.RESPONSE_ERROR);
        CodecUtils.writeUB2(buffer, packet.getErrorNumber());
        buffer.writeBytes(packet.getSqlState());
        buffer.writeBytes(messageBytes);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy