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

io.vertx.mssqlclient.impl.codec.TdsSslHandshakeCodec Maven / Gradle / Ivy

There is a newer version: 5.0.0.CR1
Show newest version
/*
 * Copyright (c) 2011-2021 Contributors to the Eclipse Foundation
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 * which is available at https://www.apache.org/licenses/LICENSE-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 */

package io.vertx.mssqlclient.impl.codec;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.CompositeByteBuf;
import io.netty.channel.*;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;

import static io.vertx.mssqlclient.MSSQLConnectOptions.MAX_PACKET_SIZE;
import static io.vertx.mssqlclient.impl.codec.MessageStatus.END_OF_MESSAGE;
import static io.vertx.mssqlclient.impl.codec.MessageStatus.NORMAL;
import static io.vertx.mssqlclient.impl.codec.MessageType.PRE_LOGIN;
import static io.vertx.mssqlclient.impl.codec.TdsPacket.PACKET_HEADER_SIZE;

/**
 * While handshaking, SSL payload is encapsulated in TDS PRELOGIN packets.
 * 

* This handler must be installed before the {@link io.netty.handler.ssl.SslHandler} in the channel pipeline. */ public class TdsSslHandshakeCodec extends CombinedChannelDuplexHandler { public TdsSslHandshakeCodec() { LengthFieldBasedFrameDecoder decoder = new LengthFieldBasedFrameDecoder(MAX_PACKET_SIZE, 2, 2, -4, PACKET_HEADER_SIZE); init(decoder, new Encoder()); } private static class Encoder extends ChannelOutboundHandlerAdapter { private CompositeByteBuf accumulator; @Override public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { if (accumulator != null) { accumulator.release(); } } @Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { if (msg instanceof ByteBuf) { accumulate(ctx.alloc(), (ByteBuf) msg); promise.setSuccess(); } else { super.write(ctx, msg, promise); } } private void accumulate(ByteBufAllocator alloc, ByteBuf byteBuf) { if (accumulator == null) { accumulator = alloc.compositeBuffer(); } accumulator.addComponent(true, byteBuf); } @Override public void flush(ChannelHandlerContext ctx) throws Exception { if (accumulator != null) { ByteBuf header = ctx.alloc().ioBuffer(PACKET_HEADER_SIZE); header.writeByte(PRE_LOGIN); header.writeByte(NORMAL | END_OF_MESSAGE); header.writeShort(PACKET_HEADER_SIZE + accumulator.writerIndex()); header.writeZero(4); ctx.write(header, ctx.voidPromise()); ctx.writeAndFlush(accumulator, ctx.voidPromise()); accumulator = null; } else { ctx.flush(); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy